@clickview/lite 0.82.0-rc.2 → 0.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/bundles.json +1 -1
  2. package/dist/css/{2258-lite-16c2b3509c.chunk.css → 275-lite-65ac7606d9.chunk.css} +1 -0
  3. package/dist/languages/en.json +1 -1
  4. package/dist/scripts/2126-1ef42f1367-lite.chunk.js +2 -0
  5. package/dist/scripts/{2126-94c739ca6b-lite.chunk.js.map → 2126-1ef42f1367-lite.chunk.js.map} +1 -1
  6. package/dist/scripts/275-3b6b9cfc9c-lite.chunk.js +3 -0
  7. package/dist/scripts/275-3b6b9cfc9c-lite.chunk.js.map +1 -0
  8. package/dist/scripts/4504-c7d0c4e1e7-lite.chunk.js +2 -0
  9. package/dist/scripts/{4504-5a8c62527f-lite.chunk.js.map → 4504-c7d0c4e1e7-lite.chunk.js.map} +1 -1
  10. package/dist/scripts/6741-1e64f67951-lite.chunk.js +3 -0
  11. package/dist/scripts/{6741-ae590891ba-lite.chunk.js.map → 6741-1e64f67951-lite.chunk.js.map} +1 -1
  12. package/dist/scripts/6948-b1b7f560c9-lite.chunk.js +3 -0
  13. package/dist/scripts/{6948-49f33f09c8-lite.chunk.js.map → 6948-b1b7f560c9-lite.chunk.js.map} +1 -1
  14. package/dist/scripts/{8-40155bcddb-lite.chunk.js → 8-a610fce3d1-lite.chunk.js} +2 -2
  15. package/dist/scripts/{8-40155bcddb-lite.chunk.js.map → 8-a610fce3d1-lite.chunk.js.map} +1 -1
  16. package/dist/scripts/{bundle-aff25c8310.min.js → bundle-1fa665690e.min.js} +3 -3
  17. package/dist/scripts/{bundle-aff25c8310.min.js.map → bundle-1fa665690e.min.js.map} +1 -1
  18. package/package.json +1 -1
  19. package/dist/scripts/2126-94c739ca6b-lite.chunk.js +0 -2
  20. package/dist/scripts/2258-3721ba5687-lite.chunk.js +0 -3
  21. package/dist/scripts/2258-3721ba5687-lite.chunk.js.map +0 -1
  22. package/dist/scripts/4504-5a8c62527f-lite.chunk.js +0 -2
  23. package/dist/scripts/6741-ae590891ba-lite.chunk.js +0 -3
  24. package/dist/scripts/6948-49f33f09c8-lite.chunk.js +0 -3
  25. /package/dist/scripts/{2258-3721ba5687-lite.chunk.js.LICENSE.txt → 275-3b6b9cfc9c-lite.chunk.js.LICENSE.txt} +0 -0
  26. /package/dist/scripts/{6741-ae590891ba-lite.chunk.js.LICENSE.txt → 6741-1e64f67951-lite.chunk.js.LICENSE.txt} +0 -0
  27. /package/dist/scripts/{6948-49f33f09c8-lite.chunk.js.LICENSE.txt → 6948-b1b7f560c9-lite.chunk.js.LICENSE.txt} +0 -0
  28. /package/dist/scripts/{bundle-aff25c8310.min.js.LICENSE.txt → bundle-1fa665690e.min.js.LICENSE.txt} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"scripts/6948-49f33f09c8-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/calendar/flight-request/CalendarRequests.ts","file:///app/packages/libs/shared/src/apps/subjects/components/audience-item/audience-item.scss","file:///app/packages/libs/shared/src/apps/subjects/components/audience-item/AudienceItem.tsx","file:///app/packages/libs/shared/src/apps/subjects/constants/DashboardStatusConfig.ts","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/dashboard-status-badge.scss","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/preview-banner/preview-banner.scss","file:///app/packages/libs/shared/src/apps/subjects/components/preview-banner/PreviewBanner.tsx","file:///app/packages/libs/shared/src/components/back-button/BackButton.tsx","file:///app/packages/libs/shared/src/components/banner-header/banner-header.scss","file:///app/packages/libs/shared/src/components/banner-header/BannerHeader.tsx","file:///app/packages/libs/shared/src/components/pill-tab-selector/PillTabSelector.tsx","file:///app/packages/libs/shared/src/enums/FeedbackType.ts","file:///app/packages/libs/shared/src/errors/handlers/HttpErrorHandlers.ts","file:///app/packages/libs/shared/src/flight-requests/FeedbackRequests.ts","file:///app/packages/libs/shared/src/hooks/UseHandleObjectError.ts","file:///app/packages/libs/shared/src/hooks/useBreadcrumbs.ts","file:///app/packages/libs/shared/src/utils/FeedbackFormHelper.ts","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/table-of-contents.scss","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-coming-soon/ClassificationComingSoon.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/audience-filter/AudienceFilter.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/audiences/ClassificationDashboardAudiences.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/classification-tabs.scss","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/ClassificationTabs.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-dashboard-nav/ClassificationDashboardNav.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/ClassificationDashboard.tsx","file:///app/packages/libs/shared/src/apps/subjects/hooks/useGetTopicsWidgets.ts","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/partial-loading/PartialClassificationDashboard.tsx","file:///app/packages/libs/shared/src/flight-requests/FollowRequests.ts","file:///app/packages/projects/lite/src/apps/subjects/errors/TopicNotFoundError.ts","file:///app/packages/projects/lite/src/apps/subjects/views/classification/curated-classification-view.scss","file:///app/packages/projects/lite/src/apps/subjects/views/classification/CuratedClassificationView.tsx","file:///app/packages/projects/lite/src/apps/subjects/hooks/useFetchClassificationDashboard.ts","file:///app/packages/libs/shared/src/components/pill-tab-selector/pill-tab-selector.scss"],"sourcesContent":["import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { CalendarEvent, CalendarEventContentType } from 'libs/shared/interfaces';\n\nexport const CalendarRequests = {\n calendarEvents(\n from: string,\n to: string,\n presentationId: string\n ): Flight.PublicRequest {\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/discover/special-events/content', { from, to, presentationId }),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/special-events/content`, { from, to, presentationId }),\n key: `presentation:${presentationId}:events:from:${from}:to${to}`\n };\n },\n\n nextTopicSpecialEvent(\n classificationId: string,\n presentationId: string\n ): Flight.PublicRequest {\n const params = {\n presentationId,\n limit: 1,\n from: DateHelper.format(new Date(), 'YYYY-MM-DD'),\n objectType: CalendarEventContentType.Classification\n };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/special-events/object/${classificationId}/next-events`, params),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/special-events/object/${classificationId}/next-events`, params),\n key: `presentation:${presentationId}:events:classification:${classificationId}`,\n formatData: (events: CalendarEvent[]) => ArrayHelper.first(events)\n };\n }\n};\n","// extracted by mini-css-extract-plugin\nexport default {\"disabled\":\"pERi4\",\"disabledHighlighted\":\"AxyWm\",\"badge\":\"KmfP8\"};","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport styles from './audience-item.scss';\n\nconst namespace = 'shared.audienceItem';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction lowerCaseToTitleCase(str: string): string {\n return str.split(' ').map((s: string) => s.charAt(0).toUpperCase() + s.substring(1)).join(' ');\n}\n\nfunction getColourClass(highlight: boolean, isDisabled: boolean): string {\n if (highlight) return isDisabled ? `${styles.disabledHighlighted} text-light` : 'bg-gray-900 text-light';\n if (isDisabled) return `${styles.disabled} text-secondary`;\n return 'bg-light';\n}\n\ninterface AudienceItemProps {\n audience: PresentationAudience;\n highlight: boolean;\n setAudience?: (audience: PresentationAudience, highlight: boolean) => void;\n isDisabled?: boolean;\n extraClasses?: string;\n}\n\nAudienceItem.defaultProps = {\n extraClasses: ''\n};\n\nexport function AudienceItem(props: AudienceItemProps): React.ReactElement {\n const { audience, highlight, setAudience, isDisabled, extraClasses } = props;\n\n const colourClass = getColourClass(highlight, isDisabled);\n const cursorClass = isDisabled ? 'cursor-default' : 'cursor-pointer';\n const className = `${styles.badge} lh-1 rounded-pill d-inline-block me-1 user-select-none ${cursorClass} ${colourClass} ${extraClasses}`;\n\n const onClick = () => {\n if (isDisabled || !FunctionHelper.isFunction(setAudience))\n return;\n\n setAudience(audience, !highlight);\n };\n\n return (\n <button\n type='button'\n className={className}\n onClick={onClick}\n role='checkbox'\n aria-checked={highlight}\n aria-label={`${getPhrase('ariaFilter')} ${audience.name}`}\n disabled={isDisabled}\n >\n {lowerCaseToTitleCase(audience.name)}\n </button>\n );\n}","import { localSvgs } from 'libs/shared/images/svg';\nimport { DashboardStatus } from 'libs/shared/interfaces/models/Dashboard';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\ninterface DashboardStatusConfigType {\n statusName: string;\n actionName: string;\n svgName: localSvgs;\n svgColorClassName: string;\n}\n\nexport const DashboardStatusConfig: Record<DashboardStatus, DashboardStatusConfigType> = {\n [DashboardStatus.Archived]: {\n svgName: cvSvgLibrary.Archive,\n svgColorClassName: 'text-secondary',\n actionName: 'Archive',\n statusName: 'Archived'\n },\n [DashboardStatus.Draft]: {\n svgName: cvSvgLibrary.Edit,\n svgColorClassName: '',\n actionName: 'Draft',\n statusName: 'Draft'\n },\n [DashboardStatus.Published]: {\n svgName: cvSvgLibrary.VisibleOn,\n svgColorClassName: 'text-success',\n actionName: 'Publish',\n statusName: 'Published'\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"badge\":\"ciO47\",\"draftLight\":\"A6Yi7\",\"draftDark\":\"fkXBX\",\"published\":\"Ovzwy\",\"archived\":\"r_dco\"};","import React from 'react';\n\nimport { DashboardStatusConfig } from 'libs/shared/apps/subjects/constants/DashboardStatusConfig';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { DashboardStatus } from 'libs/shared/interfaces';\n\nimport styles from './dashboard-status-badge.scss';\n\nfunction getClassName(props: DashboardStatusBadgeProps): string {\n let className = `rounded-pill d-flex align-items-center ps-2 py-1 fw-semibold ms-2 ${styles.badge}`;\n\n switch (props.status) {\n case DashboardStatus.Published:\n className += ` ${styles.published}`;\n break;\n case DashboardStatus.Archived:\n className += ` ${styles.archived}`;\n break;\n case DashboardStatus.Draft:\n className += ` ${props.darkMode ? styles.draftDark : styles.draftLight}`;\n break;\n }\n\n if (props.wrapperClassName)\n className += ` ${props.wrapperClassName}`;\n\n return className;\n}\n\ninterface DashboardStatusBadgeProps {\n status: DashboardStatus;\n darkMode?: boolean;\n wrapperClassName?: string;\n}\n\nexport function DashboardStatusBadge(props: DashboardStatusBadgeProps): JSX.Element {\n const { statusName, svgName } = DashboardStatusConfig[props.status];\n\n return (\n <div className={getClassName(props)}>\n <SvgContainer svgName={svgName} />\n <div>{statusName}</div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"stickyWrapper\":\"zhw6K\",\"badgeWrapper\":\"NOvn1\",\"badge\":\"pxQSR\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { DashboardStatusBadge } from 'libs/shared/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge';\nimport { EmojiText } from 'libs/shared/components/emoji-text/EmojiText';\nimport { DashboardStatus } from 'libs/shared/interfaces';\n\nimport styles from './preview-banner.scss';\n\nconst namespace = 'shared.classificationPreviewBanner';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface PreviewBannerProps {\n status: DashboardStatus;\n type: 'company' | 'topic';\n}\n\nexport function PreviewBanner(props: PreviewBannerProps): JSX.Element {\n return (\n <div className={`${styles.stickyWrapper} py-2 d-flex justify-content-space-between bg-dark text-white mx-2 rounded`}>\n <div className={`position-absolute d-flex ${styles.badgeWrapper}`}>\n <DashboardStatusBadge status={props.status} wrapperClassName={`${styles.badge}`} darkMode />\n </div>\n <div className='flex-grow-1'>\n <h1 className='text-center my-3 h5'>\n <EmojiText emoji='👀' />\n {getPhrase(props.type === 'topic' ? 'topicTitle' : 'companyTitle')}\n </h1>\n </div>\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.backButton';\n\ninterface BackButtonProps {\n appLink: Core.AppLink;\n backToName?: string;\n color?: 'black' | 'white';\n extraClasses?: string;\n /**\n * Whether or not the button text has a text shadow. Defaults to true\n */\n textShadow?: boolean;\n}\n\nBackButton.defaultProps = {\n color: 'black',\n extraClasses: ''\n};\n\nexport function BackButton(props: BackButtonProps): React.ReactElement {\n const { backToName, appLink, color, extraClasses, textShadow } = {\n textShadow: true,\n ...props\n };\n\n const backPhrase = backToName\n ? LanguageService.getPhrase(namespace, 'backTo', { backToName })\n : LanguageService.getPhrase(namespace, 'back');\n\n const colorClass = color === 'black' ? '' : 'text-white';\n const textShadowClass = textShadow ? 'text-shadow' : '';\n\n return (\n <AppLink\n appLink={appLink}\n className={`d-inline-flex align-items-center h5 mb-0 ${extraClasses} ${colorClass} ${textShadowClass}`}\n >\n <SvgContainer svgName={cvSvgLibrary.ChevronLeft} size={SvgContainerSize.Medium} />\n <span className='ms-1'>{backPhrase}</span>\n </AppLink>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"bannerContent\":\"sSCTB\",\"actionsContainer\":\"Z5WI2\",\"bannerContentWithLogo\":\"rgs7Q\",\"container\":\"M51HJ\",\"logoContainer\":\"vkeJk\",\"logoContainerLeft\":\"M3U9B\",\"logoHeading\":\"EtRwC\",\"specialEventContainer\":\"rOxDc\",\"headingLarge\":\"_8pnV\",\"heading\":\"JXVBH\"};","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ComingSoonTag } from 'libs/shared/apps/calendar/components/coming-soon-tag/ComingSoonTag';\nimport { GenericCalendarDate } from 'libs/shared/apps/calendar/components/generic-calendar-date/GenericCalendarDate';\nimport { CalendarTheme } from 'libs/shared/apps/calendar/interfaces/CalendarTheme';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { BackButton } from 'libs/shared/components/back-button/BackButton';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { ImageMinDimensions } from 'libs/shared/constants/ImageSizes';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ImageSize, ImageType, ResizeType } from 'libs/shared/enums/Images';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Banner, CalendarEvent, Logo } from 'libs/shared/interfaces';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport styles from './banner-header.scss';\n\nconst RATIO = `${ImageMinDimensions[ImageType.Banners].width}:${ImageMinDimensions[ImageType.Banners].height}`;\nconst DEFAULT_WIDTH = 1200; // This is ImageSize.Large for a Banner.\nconst LARGE_SCREEN_WIDTH = 1920;\n\nfunction useGetImageWidth(): number {\n const breakpoints = useBreakpoints();\n\n if (breakpoints.xxl)\n return LARGE_SCREEN_WIDTH;\n\n return DEFAULT_WIDTH;\n}\n\nfunction getSizeClass(heading: string): string {\n if (heading.length < 160)\n return 'h1';\n\n return styles.headingLarge;\n}\n\ninterface BannerHeaderProps {\n heading: string;\n banner?: Banner;\n bannerClassName?: string;\n imageCdnUrl?: string;\n logo?: Logo;\n logoBgColour?: string;\n actions?: ActionOptions[];\n specialEvent?: CalendarEvent;\n backButtonAppLink?: Core.AppLink;\n backButtonText?: string;\n backButtonClasses?: string;\n sortComponent?: JSX.Element;\n blockColourClass?: string;\n actionsDropdownClassName?: string;\n detailsComponent?: () => React.ReactElement;\n imageOptions?: ImageOptions;\n showComingSoon?: boolean;\n alignLogoLeft?: boolean;\n calendarTheme?: CalendarTheme;\n}\n\nconst namespace = 'shared.bannerHeader';\n\nexport const BannerHeader = React.memo(function(props: React.PropsWithChildren<BannerHeaderProps>): React.ReactElement {\n const { heading, banner, imageCdnUrl, actions, sortComponent, blockColourClass, specialEvent } = props;\n\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n const imageWidth = useGetImageWidth();\n\n const specialEventIsToday = React.useMemo(() => {\n if (!specialEvent || props.showComingSoon)\n return false;\n\n const today = DateHelper.format(new Date(), 'YYYY-MM-DD');\n\n if (!specialEvent.endDate)\n return specialEvent.startDate === today;\n\n return specialEvent.startDate <= today && specialEvent.endDate >= today;\n }, [specialEvent]);\n\n function getSpecialEventMonthText(specialEvent: CalendarEvent): string {\n if (!specialEvent.endDate)\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n if (DateHelper.isSame(specialEvent.startDate, specialEvent.endDate, 'month'))\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n return `${DateHelper.format(specialEvent.startDate, 'MMM')} - ${DateHelper.format(specialEvent.endDate, 'MMM')}`;\n }\n\n const imageOptions = props.imageOptions || {\n width: imageWidth,\n ratio: RATIO,\n resizeType: ResizeType.Cover\n };\n\n const url = !!banner && !!imageCdnUrl && ImageHelper.createBannerUrl(banner, {\n fallbackBaseUrl: imageCdnUrl,\n fallbackCategoryName: heading,\n type: ImageType.Banners\n }, imageOptions);\n\n const containerProps: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> = {\n className: `banner banner-header ${props.bannerClassName}`,\n style: url ? { backgroundImage: `url('${url}')` } : {}\n };\n\n if (!banner && blockColourClass) {\n delete containerProps.style;\n containerProps.className += ` ${blockColourClass}`;\n }\n\n const DetailsComponent = props.detailsComponent;\n\n const logoFallbackBgClassName = getBgColorClass(props.heading, BG_COLOUR_CLASS_NAMES);\n\n return PortalHelper.renderInPortalIfExists(\n // \"banner\" is used in playlists in Online. banner-header is used by all other projects\n <header {...containerProps}>\n <div className={`container ${styles.container} position-relative inner-banner`}>\n {props.backButtonAppLink && (\n <div className='pt-3'>\n <BackButton\n appLink={props.backButtonAppLink}\n backToName={props.backButtonText}\n extraClasses={props.backButtonClasses}\n color='white'\n />\n </div>\n )}\n \n <div className={`${props.alignLogoLeft ? 'position-absolute top-50 start-0 translate-middle-y w-100 ps-4' : `${styles.bannerContent} px-2 ${props.logo?.url ? styles.bannerContentWithLogo : ''}`}`}>\n {!!specialEvent && (\n <div className={`position-relative ${styles.specialEventContainer}`}>\n <GenericCalendarDate\n body={{\n type: specialEvent.endDate ? 'range' : 'day',\n text: specialEvent.endDate\n ? `${DateHelper.format(specialEvent.startDate, 'DD')}-${DateHelper.format(specialEvent.endDate, 'DD')}`\n : DateHelper.format(specialEvent.startDate, 'DD')\n }}\n month={getSpecialEventMonthText(specialEvent)}\n theme={props.calendarTheme}\n />\n </div>\n )}\n <div>\n {specialEventIsToday && (\n <div className='rounded-pill py-1 px-2 my-1 me-1 fw-semibold bg-light-blue lh-1 d-inline-block'>\n <Text namespace={namespace} phrase='onToday' />\n </div>\n )}\n {props.showComingSoon && (\n <ComingSoonTag className='pe-2 fw-semibold mb-1 rounded-pill justify-content-start text-nowrap' />\n )}\n <div className='d-flex align-items-center'>\n {props.alignLogoLeft && props.logo?.url &&\n <div className={`${styles.logoContainerLeft} d-none d-md-block rounded-circle overflow-hidden me-3 ${logoFallbackBgClassName}`}>\n <LazyImage\n src={ImageHelper.createUrl(props.logo?.url, { size: ImageSize.Medium })}\n style={{ backgroundColor: props.logoBgColour }}\n />\n </div>\n }\n <h1 className={`text-white text-shadow pe-3 position-static ${styles.heading} ${getSizeClass(heading)} ${props.alignLogoLeft ? 'w-50' : ''}`}>\n {heading}\n {DetailsComponent && <DetailsComponent />}\n </h1>\n </div>\n </div>\n {!!actions && (\n <div className={styles.actionsContainer}>\n <Actions\n actions={actions}\n sortComponent={sortComponent}\n actionsDropdownClassName={props.actionsDropdownClassName}\n />\n </div>\n )}\n </div>\n {!props.alignLogoLeft && !!props.logo?.url &&\n <div className={styles.logoContainer}>\n <img\n src={ImageHelper.createUrl(props.logo.url, { size: ImageSize.Medium })}\n className='rounded-circle'\n />\n </div>\n }\n </div>\n </header>,\n portalContainerContext?.container\n );\n}, (prevProps, nextProps): boolean => (\n prevProps.actions === nextProps.actions\n && prevProps.heading === nextProps.heading\n && prevProps.logo?.url === nextProps.logo?.url\n));\n\nexport function PartialBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className={`partial-banner partial-loading-background ${styles.banner}`} />,\n portalContainerContext?.container\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Badge, BadgeType } from 'libs/shared/components/badges/Badge';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\n\nimport { SvgContainer } from '../svg-container/SvgContainer';\n\nimport styles from './pill-tab-selector.scss';\n\ninterface TabContentsProps {\n tab: PillTab;\n}\n\nfunction TabContents(props: TabContentsProps): JSX.Element {\n return (\n <>\n {!!props.tab.svgName && (\n <div className={props.tab.name ? 'pe-1' : ''}>\n <SvgContainer svgName={props.tab.svgName} />\n </div>\n )}\n\n {props.tab.name}\n\n {typeof (props.tab.count) === 'number' && (\n <div className='ps-2'>\n <Badge type={BadgeType.Count} data={props.tab.count} />\n </div>\n )}\n </>\n );\n}\n\nexport interface PillTab {\n name: string;\n active: boolean;\n svgName?: string;\n\n className?: string;\n\n appLink?: Core.AppLink;\n onSelect?: () => void;\n\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n\n count?: number;\n}\n\ninterface PillTabSelectorProps {\n tabs: PillTab[];\n containerRef?: (el: HTMLElement) => void;\n listClassName?: string;\n className?: string;\n borderRadius?: 'sm' | 'lg'\n}\n\nPillTabSelector.defaultProps = {\n borderRadius: 'lg'\n};\n\nexport function PillTabSelector(props: PillTabSelectorProps): JSX.Element {\n function onSelectTab(tab: PillTab): void {\n if (tab.active || !tab.onSelect)\n return;\n\n tab.onSelect();\n\n if (tab.analyticsData && tab.analyticsOptions)\n AnalyticsHelper.logUserAction(tab.analyticsData, tab.analyticsOptions);\n }\n\n return (\n <nav className={props.className ?? ''} ref={props.containerRef}>\n <ul className={`\n list-unstyled d-inline-block m-0 ${styles.pillTabSelector}\n ${props.borderRadius ? styles.radiusSmall : ''}\n ${props.listClassName}\n `}>\n {props.tabs.map((tab, index) => {\n return (\n <li\n className={`\n p-0 ${styles.tab} ${tab.active ? 'btn btn-dark' : 'btn btn-outline-dark'}\n ${tab.name ? styles.minWidth : ''} ${tab.className}\n `}\n key={index}\n >\n {tab.appLink ? (\n <AppLink\n appLink={tab.appLink}\n analyticsData={tab.analyticsData}\n analyticsOptions={tab.analyticsOptions}\n className={`\n cursor-pointer d-flex align-items-center justify-content-center\n text-decoration-none text-reset px-2 text-nowrap ${styles.tabLink}\n `}\n >\n <TabContents tab={tab} />\n </AppLink>\n ) : (\n <DivButton\n className={`\n cursor-pointer d-flex align-items-center justify-content-center\n text-decoration-none text-reset px-2 text-nowrap ${styles.tabLink}\n `}\n onClick={() => onSelectTab(tab)}\n >\n <TabContents tab={tab} />\n </DivButton>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n","export enum FeedbackType {\n Other,\n SuggestImprovement,\n ReportBug,\n RequestVideo,\n RaiseIssue,\n GivePraise,\n Footer,\n RequestLivestream\n}","import { BaseError } from 'libs/common/backbone/core/BaseError';\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Core } from 'libs/common/core';\n\nimport { NotFoundError } from 'libs/shared/errors/general/not-found/NotFoundError';\nimport { PrivateResourceError } from 'libs/shared/errors/general/private-resource/PrivateResourceError';\nimport { RegionLockedResourceError } from 'libs/shared/errors/general/region-locked-resource/RegionLockedResourceError';\nimport { UnspecifiedError } from 'libs/shared/errors/general/unspecified-error/UnspecifiedError';\nimport { VideoTypes } from 'libs/shared/interfaces';\n\nexport interface HttpErrorMap {\n notFound?: new () => BaseError;\n forbidden?: {\n rating?: new (description: string) => BaseError;\n yearLevel?: new (description: string) => BaseError;\n region?: new () => BaseError;\n privacy?: new (video?: VideoTypes) => BaseError;\n };\n badRequest?: new () => BaseError;\n internalServerError?: new () => BaseError;\n}\n\nexport type IgnoreHttpErrorMap = {\n [key in keyof HttpErrorMap]: boolean;\n};\n\nconst defaultErrors: HttpErrorMap = {\n notFound: NotFoundError,\n forbidden: {\n rating: PrivateResourceError,\n yearLevel: PrivateResourceError,\n region: RegionLockedResourceError,\n privacy: PrivateResourceError\n },\n badRequest: UnspecifiedError,\n internalServerError: UnspecifiedError\n};\n\nexport function handleHttpError(\n info: HttpStatus | Xhr,\n customErrorMap: HttpErrorMap = {},\n /**\n * Prevent certain errors in the errorMap from being thrown\n * so that you may implement your own handler\n */\n ignoreMap: IgnoreHttpErrorMap = {}\n): void {\n if (!info)\n return;\n\n let statusCode: HttpStatus;\n\n if (typeof(info) === 'number') {\n statusCode = info;\n } else {\n statusCode = info.status;\n }\n\n const errorMap = {\n ...defaultErrors,\n ...customErrorMap\n };\n\n if (!statusCode)\n return;\n\n if (!Core.ErrorHelper.isStatusCodeError(statusCode))\n return;\n\n if (statusCode === HttpStatus.InternalServer) {\n if (!ignoreMap.internalServerError)\n Core.ErrorHelper.throw(new UnspecifiedError());\n return;\n }\n\n if (statusCode === HttpStatus.NotFound) {\n if (!ignoreMap.notFound)\n Core.ErrorHelper.throw(new errorMap.notFound());\n return;\n }\n\n if (statusCode === HttpStatus.Forbidden) {\n /**\n * TODO: Work out how to go about handling all forbidden errors, such as region locking, year levels,\n * ratings, and privacy.\n */\n if (!ignoreMap.forbidden)\n Core.ErrorHelper.throw(new errorMap.forbidden.privacy());\n return;\n }\n\n if (!ignoreMap.badRequest)\n Core.ErrorHelper.throw(new errorMap.badRequest());\n}\n\nexport function handleXhrError(xhr: Xhr, customErrorMap?: HttpErrorMap): void {\n handleHttpError(xhr.status, customErrorMap);\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/react/index';\n\nimport { FeedbackFormRequest } from 'libs/shared/interfaces/requests/FeedbackFormRequest';\n\nexport const FeedbackRequests = {\n submitFeedback(requestData: FeedbackFormRequest, formValues: Record<string, string>): Flight.Request {\n return {\n url: '{gateway}/v1/feedback',\n key: 'submit:feedback',\n type: HttpVerbs.POST,\n data: {\n ...requestData,\n ...formValues\n }\n };\n }\n};","import { useEffect } from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { handleHttpError, HttpErrorMap, IgnoreHttpErrorMap } from 'libs/shared/errors/handlers/HttpErrorHandlers';\n\nfunction generateCacheKey(flightObjs: Array<Flight.Response<any>>): string {\n return flightObjs.map(obj => obj.statusCode).join(':');\n}\n\n// TODO: Change this to just `useHandleHttpError` and only accept a status code.\nexport function useHandleObjectError(\n _flightObjs: Flight.Response<any> | Array<Flight.Response<any>>,\n customErrors?: HttpErrorMap,\n ignoreErrors?: IgnoreHttpErrorMap\n): void {\n const flightObjs = Array.isArray(_flightObjs) ? _flightObjs : [_flightObjs];\n\n useEffect(() => {\n flightObjs.forEach(obj => {\n handleHttpError(obj.statusCode, customErrors, ignoreErrors);\n });\n }, [ generateCacheKey(flightObjs), customErrors, ignoreErrors ]);\n}","import React from 'react';\n\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { BreadcrumbService } from 'libs/shared/services/BreadcrumbService';\n\nexport function useBreadcrumbs(current: Breadcrumb): Breadcrumb[] {\n const [ match, useBuilder ] = React.useMemo(() => BreadcrumbService.getBuilder(), []);\n\n const breadcrumbs = useBuilder(match);\n\n if (!breadcrumbs || !current)\n return breadcrumbs;\n\n return [ ...breadcrumbs, { ...current, active: true }];\n}\n\n","import Dropzone from 'dropzone';\n\nimport { UploadItem } from 'libs/shared/apps/upload/services/UploadService';\nimport { FileExtensions } from 'libs/shared/apps/upload/utils/FileExtensionsHelper';\nimport { CountryCode } from 'libs/shared/enums/CountryCode';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { CurrentUser, Customer } from 'libs/shared/interfaces';\nimport { FeedbackUserDetails } from 'libs/shared/interfaces/requests/FeedbackFormRequest';\n\nconst COUNTRY_CODE_TAGS: { [key in CountryCode]: string } = {\n [CountryCode.AU]: 'au',\n [CountryCode.NZ]: 'nz',\n [CountryCode.UK]: 'uk',\n [CountryCode.US]: 'us',\n [CountryCode.CA]: 'ca'\n};\n\nexport const FeedbackFormHelper = {\n getUserInfo: (\n currentUser: CurrentUser,\n customer: Customer\n ): FeedbackUserDetails => {\n return {\n id: currentUser.id,\n username: currentUser.username,\n email: currentUser.email,\n userType: currentUser.role === UserRole.Admin ? 'Admin' : 'Staff',\n customerId: currentUser.customerId,\n cvcId: customer.crmId,\n customerName: customer.name,\n instanceRegion: currentUser.instanceRegion,\n contentRegion: currentUser.contentRegion,\n firstName: currentUser.givenName,\n lastName: currentUser.familyName\n };\n },\n\n mapCountryCodeToTag: (countryCode: CountryCode): string => {\n return COUNTRY_CODE_TAGS[countryCode.toLowerCase() as CountryCode];\n },\n\n getTags: (currentUser: CurrentUser, product: ProductId, hasStudentExperience: boolean, extraTags: string[]) => {\n const tags = [\n product,\n ...extraTags\n ];\n\n tags.push(hasStudentExperience ? 'student' : 'staff');\n \n if (currentUser.role === UserRole.Admin)\n tags.push('administrator');\n \n const countryCodeTag = FeedbackFormHelper.mapCountryCodeToTag(currentUser.countryCode);\n \n if (countryCodeTag)\n tags.push(countryCodeTag);\n\n return tags;\n },\n\n categorizeFiles(files: UploadItem[]) {\n return files.reduce((result, file) => {\n const fileInfo = file.get('fileInfo');\n if (Dropzone.isValidFile(file.get('file'), FileExtensions.VIDEO)) {\n result.videoUrls.push(fileInfo?.url);\n } else {\n result.imageUrls.push(fileInfo?.url);\n }\n return result;\n }, {\n imageUrls: [],\n videoUrls: []\n });\n }\n};","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Classification } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nconst namespace = 'subject.classificationHeaderDetails';\n\nconst Separator = ({ className }: { className: string }) =>\n <span className={className}>&bull;</span>;\n\ninterface ClassificationHeaderDetailsProps {\n classification: Classification;\n}\n\nexport function ClassificationHeaderDetails(props: ClassificationHeaderDetailsProps): React.ReactElement {\n const {\n dashboardVideoCount,\n childDashboardVideoCount,\n dashboardResourceCount,\n childDashboardResourceCount,\n childClassificationCount\n } = TopicsHelper.getCounts(props.classification);\n\n const videoCount = dashboardVideoCount + childDashboardVideoCount;\n const resourceCount = dashboardResourceCount + childDashboardResourceCount;\n\n return (\n <p className='mb-n1 font-size-normal fw-normal mt-1'>\n {!!childClassificationCount && (\n <Text\n namespace={namespace}\n phrase='topics'\n options={{ count: childClassificationCount.toLocaleString(), smartCount: childClassificationCount }}\n />\n )}\n\n {!!videoCount && (\n <>\n {childClassificationCount > 0 && <Separator className='mx-2' />}\n <Text\n namespace={namespace}\n phrase='videos'\n options={{ count: videoCount.toLocaleString(), smartCount: videoCount }}\n />\n </>\n )}\n {!!resourceCount && (\n <>\n <Separator className='mx-2' />\n <Text\n namespace={namespace}\n phrase='resources'\n options={{ count: resourceCount.toLocaleString(), smartCount: resourceCount }}\n />\n </>\n )}\n </p>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'subjects.curatedClassificationEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CuratedClassificationEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function CuratedClassificationEmptyState(props: CuratedClassificationEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('headingForNP')} />\n {!props.isReadonly ? (\n <EmptyState.Heading>\n <Text phrase='headingForNP' />\n </EmptyState.Heading>\n ) : (\n <>\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='headingForCurator' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={cvSvgLibrary.Plus}\n disabled={isArchived}\n />\n </Tooltip>\n </>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"container\":\"k1iOO\",\"mobile\":\"QwoBj\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { TableOfContentsList } from 'libs/shared/components/table-of-contents-list/TableOfContentsList';\nimport { CuratedWidget } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './table-of-contents.scss';\n\ninterface TableOfContentsContainerProps {\n widgets: CuratedWidget[];\n title: string;\n activeId: string;\n appLink?: Core.AppLink;\n clickable?: boolean;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n isSmallScreen?: boolean;\n}\ninterface TableOfContentsProps extends TableOfContentsContainerProps {\n getAppLink: (widget: CuratedWidget) => Core.AppLink\n}\n\nfunction TableOfContentsMobile(props: TableOfContentsProps) {\n const [ isExpanded, setIsExpanded ] = React.useState(false);\n\n function logUserAction() {\n const analyticsOptions = {\n actionType: !isExpanded ? UserAction.Open : UserAction.Hide,\n entity: EntityType.TableOfContents,\n location: LocationContext.Dashboard\n };\n\n AnalyticsHelper.logUserAction(props.analyticsData, analyticsOptions);\n }\n\n function onClickIcon() {\n setIsExpanded(!isExpanded);\n logUserAction();\n }\n\n return (\n <div className={`${styles.mobile} d-inline-flex gap-1`}>\n \n {isExpanded && (\n <div className='bg-white px-3 pt-3 pb-2 border border-dark rounded-1 ps-3'>\n <h2 className='h5'>{props.title}</h2>\n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n onItemClick={() => setIsExpanded(false)}\n />\n </div>\n )}\n <div className={styles.container}>\n <IconButton\n className='btn btn-outline-dark'\n svgName={cvSvgLibrary.TableOfContents}\n onClick={onClickIcon}\n />\n </div>\n </div>\n );\n}\n\nfunction TableOfContents(props: TableOfContentsProps): JSX.Element {\n return (\n <aside className='col-3 order-1'>\n <div className={`${styles.container} ps-3`}>\n <h2 className='h5'>{props.title}</h2>\n \n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n />\n </div>\n </aside>\n );\n}\n\nexport function TableOfContentsContainer(props: TableOfContentsContainerProps): JSX.Element {\n function getAppLink(widget: CuratedWidget): Core.AppLink {\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n \n const params: HashObject = currentAppLink.params\n ? { ...(currentAppLink.params as HashObject) }\n : {};\n\n params.tocId = widget.id;\n\n return {\n ...currentAppLink,\n params\n };\n }\n\n return (\n <>\n {!props.isSmallScreen\n ? <TableOfContents {...props} getAppLink={getAppLink} />\n : <TableOfContentsMobile {...props} getAppLink={getAppLink} />\n }\n </>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'subjects.teacherOnlyEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface TeacherOnlyEmptyStateProps {\n imageUrl: string;\n ctaAppLink?: () => Core.AppLink;\n}\n\nexport function TeacherOnlyEmptyState(props: TeacherOnlyEmptyStateProps): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('heading')} />\n <EmptyState.Heading>\n <Text phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text phrase='info' />\n </EmptyState.Info>\n\n <EmptyState.Cta\n text={getPhrase('cta')}\n appLink={props.ctaAppLink?.()}\n className='btn btn-dark'\n />\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Classification } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'subjects.classificationComingSoon';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ComingSoonProps {\n data: Classification;\n onToggleFollow?: () => void;\n canFollowSubjects: boolean;\n imageUrl: string;\n showFollowButtonSpinner: boolean;\n showSignUp: boolean;\n signUpAppLink: Core.AppLink;\n}\n\nexport function ClassificationComingSoon(props: ComingSoonProps): JSX.Element {\n const isFollowing = !!props.data.followers?.data?.length;\n function onClick(): void {\n props.onToggleFollow?.();\n }\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState className='pt-0'>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('comingSoon')} />\n\n <EmptyState.Heading>\n <Text phrase='comingSoon' />\n </EmptyState.Heading>\n\n <EmptyState.Info>\n <Text phrase={props.showSignUp ? 'infoAnon' : 'info'} />\n </EmptyState.Info>\n\n {props.canFollowSubjects && (\n <ActionButton\n svgName={isFollowing ? cvSvgLibrary.BellFilled : cvSvgLibrary.Bell}\n onClick={onClick}\n showSpinner={props.showFollowButtonSpinner}\n className={`btn follow-btn me-2 ${isFollowing ? 'btn-outline-dark' : 'btn-dark'}`}\n >\n <Text phrase={isFollowing ? 'following' : 'follow'} />\n </ActionButton>\n )}\n\n {props.showSignUp && !props.canFollowSubjects && (\n <AppLink\n appLink={props.signUpAppLink}\n className='btn btn-dark d-none d-lg-inline-block'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.ClassificationComingSoon,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n }}\n analyticsData={{}}\n tag='button'\n >\n {getPhrase('signUp')}\n </AppLink>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","import * as React from 'react';\n\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Core } from 'libs/common/core';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AudienceItem } from 'libs/shared/apps/subjects/components/audience-item/AudienceItem';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\n\nconst namespace = 'subjects.audienceFilter';\n\ninterface AudienceFilterProps {\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n disabled?: boolean;\n appLink: Core.AppLink;\n disablePersist?: boolean;\n tooltip?: string;\n}\n\nexport function AudienceFilter(props: AudienceFilterProps): React.ReactElement {\n const { audiences, activeAudiences, appLink } = props;\n\n const isDisabled = props.disabled || !appLink;\n\n const [ , setActiveAudiences ] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n React.useEffect(() => {\n if (!props.disablePersist)\n setActiveAudiences(activeAudiences);\n }, [activeAudiences]);\n\n function onToggleAudience(audience: PresentationAudience, isSelected: boolean): void {\n if (isDisabled)\n return;\n\n const activeAudienceNames = isSelected\n ? [ ...(activeAudiences?.map(a => a.name) ?? []), audience.name ]\n : activeAudiences.map(a => a.name).filter(name => name !== audience.name);\n\n const getParams = () => {\n const otherParams = ObjectHelper.omit(appLink.params, ['a']);\n\n if (!activeAudienceNames.length)\n return otherParams;\n\n return Object.assign({}, otherParams, { a: activeAudienceNames });\n };\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params: getParams()\n }, { replace: true });\n }\n\n function onClickClearAudiences(): void {\n if (isDisabled)\n return;\n\n const params = ObjectHelper.omit(appLink.params, ['a']);\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params\n }, { replace: true });\n }\n\n if (!audiences || !audiences.length)\n return <></>;\n\n return (\n <Tooltip title={props.tooltip} spanHack>\n <div className='d-flex flex-wrap row-gap-2'>\n {audiences.map((a: PresentationAudience) => (\n <AudienceItem\n key={a.masterId}\n audience={a}\n highlight={!isDisabled && !!activeAudiences?.find(aa => aa.masterId === a.masterId)}\n setAudience={onToggleAudience}\n isDisabled={isDisabled}\n />\n ))}\n {(!isDisabled && !!activeAudiences && !!Object.keys(activeAudiences).length) && (\n <DivButton className='info-link d-inline-block ms-1' onClick={onClickClearAudiences}>\n <Text namespace={namespace} phrase='clear' />\n </DivButton>\n )}\n </div>\n </Tooltip>\n );\n}\n\nconst PARTIAL_AUDIENCES = PartialLoadingHelper.getPartialLoadingItems({ numItems: 6 });\n\nexport const PartialAudienceFilter = () => (\n <div className={'d-flex flex-wrap row-gap-2'}>\n {PARTIAL_AUDIENCES.map(({ width }, idx) => (\n <span\n key={idx}\n className='rounded-pill partial-loading-background me-1'\n dangerouslySetInnerHTML={{ __html: '&nbsp' }}\n style={{ width }}\n />\n ))}\n </div>\n);","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { AudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\ninterface ClassificationDashboardAudiencesProps {\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n appLink: Core.AppLink;\n disabled: boolean;\n disablePersist: boolean;\n tooltip: string;\n}\n\nexport function ClassificationDashboardAudiences(props: ClassificationDashboardAudiencesProps): JSX.Element {\n return (\n <AudienceFilter\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n disabled={props.disabled}\n appLink={props.appLink}\n disablePersist={props.disablePersist}\n tooltip={props.tooltip}\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"curatedTopicTab\":\"CmVlO\",\"tabTransition\":\"rX31t\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTab, PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\nimport { useProductTipsContext } from 'libs/shared/context/product-tips-context/ProductTipsContext';\nimport { Breakpoints, useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Classification, Presentation } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { useDirectoryTabProductTipSwitcher } from '../../../hooks/useDirectoryTabProductTipSwitcher';\n\nimport styles from './classification-tabs.scss';\n\nconst namespace = 'shared.classificationDashboard';\n\nexport type ClassificationTab = 'new-releases' | 'all-topics' | 'curated-topic' | 'curriculum';\n\nfunction getTabs(\n props: ClassificationTabsProps,\n breakpoints: Breakpoints,\n activeTab: ClassificationTab,\n isHighlighting: boolean\n): PillTab[] {\n const showText = breakpoints.lg || breakpoints.xl || breakpoints.xxl || breakpoints.xs;\n\n function getTopicTabClassName(): string {\n let className = isHighlighting ? styles.tabTransition : '';\n\n if (breakpoints.xs)\n return className + ' w-100';\n\n if (showText)\n return className = ` ${styles.curatedTopicTab}`;\n\n return className;\n }\n\n if (TopicsHelper.isTopLevelTopic(props.classification)) {\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'newReleases') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'new-releases',\n svgName: cvSvgLibrary.Sparkle,\n analyticsData: {\n id: 'new-releases',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'newReleases'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'allTopics') : '',\n appLink: props.appLinks?.classificationDirectory?.(props.classification),\n active: activeTab === 'all-topics',\n svgName: cvSvgLibrary.Grid,\n analyticsData: {\n id: 'all-topics',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'allTopics'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationDirectory?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n }\n\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'topic') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'curated-topic',\n svgName: cvSvgLibrary.Rectangles,\n analyticsData: {\n id: 'curated-topic',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'topic'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: getTopicTabClassName()\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'curriculum') : '',\n appLink: props.appLinks?.classificationCurriculum?.(props.classification),\n active: activeTab === 'curriculum',\n svgName: cvSvgLibrary.GraduationCap,\n analyticsData: {\n id: 'curriculum',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'curriculum'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationCurriculum?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n}\n\ninterface ClassificationTabsProps {\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n classification: (classification: Classification | null) => Core.AppLink;\n classificationDirectory: (classification: Classification) => Core.AppLink;\n classificationCurriculum: (classification: Classification) => Core.AppLink;\n };\n activeTab: ClassificationTab;\n}\n\nexport function ClassificationTabs(props: ClassificationTabsProps): JSX.Element {\n const breakpoints = useBreakpoints();\n const { tab, isHighlighting } = useDirectoryTabProductTipSwitcher(props.activeTab);\n\n const { setProductTipRef } = useProductTipsContext('topics-directory-tab');\n\n return (\n <PillTabSelector\n borderRadius='sm'\n containerRef={el => setProductTipRef(el)}\n className={breakpoints.xs ? 'w-100' : ''}\n listClassName='d-flex flex-nowrap'\n tabs={getTabs(props, breakpoints, tab, isHighlighting)}\n />\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Classification, CuratedDashboard, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ClassificationDashboardAudiences } from '../audiences/ClassificationDashboardAudiences';\nimport { ClassificationTab, ClassificationTabs } from '../classification-tabs/ClassificationTabs';\n\nfunction shouldHideAudiences(\n audiences: PresentationAudience[],\n activeAudiences: PresentationAudience[],\n activeTab: ClassificationTab,\n isEmpty: boolean,\n isComingSoon: boolean\n): boolean {\n if (isComingSoon)\n return true;\n\n if (isEmpty && !activeAudiences?.length)\n return true;\n\n if (!AudienceHelper.shouldShowAudiences(audiences))\n return true;\n\n if (activeTab === 'curriculum')\n return true;\n\n return false;\n}\n\ninterface ClassificationDashboardNavProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n audience: () => Core.AppLink;\n classification: (classification: Classification | null) => Core.AppLink;\n classificationDirectory: (classification: Classification) => Core.AppLink;\n classificationCurriculum: (classification: Classification) => Core.AppLink;\n };\n activeTab: ClassificationTab;\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n getBreadcrumbs: () => Breadcrumb[];\n\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isComingSoon: boolean;\n isEmpty: boolean;\n isViewingCurrentPresentation: boolean;\n disableAudiences: boolean;\n audienceTooltip: string;\n}\n\nexport function ClassificationDashboardNav(props: ClassificationDashboardNavProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const hideAudiences = shouldHideAudiences(\n props.audiences,\n props.activeAudiences,\n props.activeTab,\n props.isEmpty,\n props.isComingSoon\n );\n\n function canShowTabs(): boolean {\n if (!props.classification || !props.dashboard)\n return false;\n\n if (CuratedDashboardHelper.isSystemGeneratedDashboard(props.dashboard.widgets))\n return false;\n\n /**\n * For our top-level topics, we can show the topic tab if the topic has a directory dashboard.\n */\n if (TopicsHelper.isTopLevelTopic(props.classification))\n return props.hasTopicDirectoryDashboard;\n\n /**\n * For our curated topics, we can show the curriculum tab if the topic has one, which it should\n */\n if (props.classification.externalMetadata?.isCurated && props.hasTopicCurriculumDashboard)\n return true;\n\n return false;\n }\n\n function getContainerClass(): string {\n let className = 'd-flex flex-column py-3 mb-3';\n\n if (!props.isComingSoon)\n className += ' border-bottom';\n\n if ((canShowTabs() || hideAudiences) && !breakpoints.xs)\n return className;\n\n return className + ' row-gap-3';\n }\n\n function getTopRowClass(): string {\n if (hideAudiences) {\n if (breakpoints.xs)\n return 'd-flex flex-column justify-content-between row-gap-3';\n\n return 'd-flex align-items-center justify-content-between';\n }\n\n let className = '';\n\n className += 'd-flex align-items-center justify-content-between mb-1';\n\n if (breakpoints.xs)\n className += ' row-gap-3 mb-0';\n\n return className;\n }\n\n function getBottomRowClass(): string {\n let className = 'd-flex align-items-end justify-content-between';\n\n if (breakpoints.xs)\n className += ' row-gap-3 flex-wrap';\n\n return className;\n }\n\n return (\n <div className={getContainerClass()}>\n <div className={getTopRowClass()}>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n\n {canShowTabs() && hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n\n <div className={getBottomRowClass()}>\n {!hideAudiences && (\n <ClassificationDashboardAudiences\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n appLink={props.appLinks.audience?.()}\n disabled={props.disableAudiences}\n tooltip={props.audienceTooltip}\n disablePersist={!props.isViewingCurrentPresentation}\n />\n )}\n\n {canShowTabs() && !hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsOptions, HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { ClassificationHeaderDetails } from 'libs/shared/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails';\nimport { CuratedClassificationEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState';\nimport { TableOfContentsContainer } from 'libs/shared/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents';\nimport { TeacherOnlyEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState';\nimport { useGetTopicsWidgets } from 'libs/shared/apps/subjects/hooks/useGetTopicsWidgets';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { VideoList } from 'libs/shared/components/video-list/VideoList';\nimport { WidgetHeader } from 'libs/shared/components/widgets/curated-widgets/components/header/WidgetHeader';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllClassificationWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { LocalPermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { useTableOfContentsActiveHeading } from 'libs/shared/hooks/useTableOfContentsActiveHeading';\nimport { useTableOfContentsScroll } from 'libs/shared/hooks/useTableOfContentsScroll';\nimport { CalendarEvent, CalendarEventContentType, Classification, CuratedDashboard, CuratedWidget, CuratedWidgetQueryParams, CurriculumData, DashboardStatus, DashboardTargetType, InteractiveMetadata, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ClassificationComingSoon } from './classification-coming-soon/ClassificationComingSoon';\nimport { ClassificationDashboardNav } from './classification-dashboard-nav/ClassificationDashboardNav';\nimport { ClassificationTab } from './classification-tabs/ClassificationTabs';\n\nconst namespace = 'shared.classificationDashboard';\n\nfunction isHeadingWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.Blurb && widget.templateId === WidgetTemplate.Heading;\n}\n\nfunction isTopicWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.CuratedClassifications || widget.widgetId === WidgetTypeId.Classifications;\n}\n\nexport interface ClassificationDashboardProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n resourceThumbnailFallbackImageUrl: string;\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isTertiaryCustomerWithoutExchange: boolean;\n tab: ClassificationTab;\n specialEvent?: CalendarEvent;\n curriculums: CurriculumData;\n\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n getBannerActions?: () => ActionOptions[];\n getBreadcrumbs?: () => Breadcrumb[];\n onToggleFollow?: (classification: Classification, locationContext: LocationContext) => void;\n canFollowSubjects: boolean;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n\n appLinks?: AllClassificationWidgetTemplates['appLinks'] & {\n signUp: () => Core.AppLink;\n widgetWizard: () => Core.AppLink;\n previewQuestions: (interactive: InteractiveMetadata) => Core.AppLink\n classificationCurriculum: (classification: Classification) => Core.AppLink;\n audience: () => Core.AppLink;\n };\n\n imageCdnUrl: string\n emptyImageUrl: string;\n comingSoonImageUrl?: string;\n\n analyticsOptions?: AnalyticsOptions;\n analyticsData?: HashObject;\n\n scrollToWidgetId?: string;\n tableOfContentsId?: string;\n\n // Means the dashboard contains no linked or working filters\n isReadonly?: boolean;\n\n // Means the dashboard is being previewed by ClickView staff either in product or in curator\n isPreviewing?: boolean;\n\n // Means the parent topic for the dashboard has a status of \"Coming Soon\"\n isComingSoon?: boolean;\n\n showFollowButtonSpinner?: boolean;\n \n isViewCurrentPresentation?: boolean;\n\n // By default widgets will always be lazyloaded. We override this behaviour only in extenuating \n // circumstances, such as dynamic rendering for SEO.\n lazyLoad?: boolean;\n\n moviesAndTv?: boolean;\n\n isTeacherOnly?: boolean;\n \n contentType?: CalendarEventContentType;\n\n isBot?: boolean;\n\n settings?: AllClassificationWidgetTemplates['settings'];\n\n commonVideoProps: CommonVideoProps;\n}\n\nClassificationDashboard.defaultProps = {\n appLinks: {}\n};\n\nexport function ClassificationDashboard(props: ClassificationDashboardProps): JSX.Element {\n const { widgets, videoList, videoListWidgetId } = useGetTopicsWidgets(props.dashboard, props.activeAudiences);\n\n const isSmallScreen = useMediaQuery(MediaQueryStrings.LGDown);\n const headingRef = React.useRef<Set<Element>>(new Set());\n\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n\n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n const [ controlledId, setControlledId ] = React.useState(props.tableOfContentsId);\n\n const [ tableOfContentActiveId, setTableOfContentActiveId ] = React.useState<string>('');\n\n const headingElements = Array.from(headingRef.current);\n useTableOfContentsScroll(headingElements, controlledId);\n useTableOfContentsActiveHeading({\n setActiveId: setTableOfContentActiveId,\n headingElements,\n controlledId,\n setControlledId\n });\n\n function shouldShowEmptyState(): boolean {\n if (props.isComingSoon)\n return false;\n\n if (props.isTeacherOnly)\n return false;\n\n if (!props.dashboard)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Archived && !props.isReadonly)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Draft && !props.isPreviewing)\n return true;\n\n if (!widgets?.length)\n return true;\n\n if (videoList && videoList.length)\n return false;\n\n return Object.values(emptyWidgets).every(state => !!state);\n }\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard),\n props.activeAudiences?.map(a => a.masterId),\n props.curriculums.preferredCurriculum?.id\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = shouldShowEmptyState();\n\n React.useEffect(() => {\n /**\n * When we add the first widget of the dashboard, the showEmptyState is `true`, the WidgetContainer is not going to be rendered to lazyload the `content`\n * so we set the emptyWidget to initial make sure the widget container is rendered to lazyload `widget.content`\n * and let the WidgetContainer to re-set the empty state based on the actual `widget.content` from backend\n */\n if (showEmptyState) {\n setEmptyWidgets(initialEmptyWidgets);\n }\n }, [widgets?.length]);\n\n const onSetIsEmpty = React.useCallback((widgetId: string, isEmpty: boolean) => {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n // The logic beneath this if-block doesn't apply to classification directories. This is because\n // classification directories don't support audience filtering, so widgets should never be empty,\n // meaning headings should never be hidden.\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.ClassificationDirectory)) {\n setEmptyWidgets(newEmptyState);\n return;\n }\n\n let index = 0;\n\n /**\n * Every time a widget is identified as empty, we check each heading blurb widget\n * to see if it should be hidden. This will be the case when all widgets beneath a heading\n * (up until the next heading) are empty.\n */\n while (index < widgets.length) {\n const currentWidget = widgets[index];\n\n if (!isHeadingWidget(currentWidget)) {\n index++;\n continue;\n }\n\n let isHeadingEmpty = true;\n let subWidgetIndex = index + 1;\n\n while (isHeadingEmpty && subWidgetIndex < widgets.length) {\n const headingSubWidget = widgets[subWidgetIndex];\n\n if (isHeadingWidget(headingSubWidget))\n break;\n\n if (!newEmptyState[headingSubWidget.id] && !isTopicWidget(headingSubWidget))\n isHeadingEmpty = false;\n\n subWidgetIndex++;\n }\n\n index = subWidgetIndex;\n\n newEmptyState[currentWidget.id] = isHeadingEmpty;\n }\n\n setEmptyWidgets(newEmptyState);\n }, [ emptyWidgets, widgets ]);\n\n function hideWidget(widget: CuratedWidget): boolean {\n return isHeadingWidget(widget) && emptyWidgets[widget.id];\n }\n\n function useLargeDashboardSpacing(): boolean {\n const target = CuratedDashboardHelper.getDashboardTargetType(props.dashboard);\n\n if (props.moviesAndTv || target === DashboardTargetType.ClassificationCurriculum)\n return false;\n\n return true;\n }\n\n function getWidgetHeading(widget: CuratedWidget, index: number): string {\n if (widget.widgetId === WidgetTypeId.ClassificationDashboardExternalMedia) {\n const previousWidget = widgets[index - 1];\n\n if (emptyWidgets[previousWidget.id])\n return widget.name.replace('Other videos', 'Videos');\n\n return widget.name;\n }\n\n return widget.name;\n }\n\n const widgetsInTableOfContents = widgets.filter(w => {\n return !hideWidget(w) && !!w.metadata?.showInTableOfContents;\n });\n\n const isTopicOnlyDashboard = widgets.every(isTopicWidget);\n\n const shouldShowTableOfContents = widgetsInTableOfContents.length >= 2;\n const shouldShowSideTableOfContents = shouldShowTableOfContents && !isSmallScreen;\n\n const shouldShowTopicCounts = (\n props.settings?.hasTopicDirectories &&\n TopicsHelper.isTopLevelTopic(props.classification) &&\n !props.isTertiaryCustomerWithoutExchange\n );\n\n /**\n * We don't put the .topic-dashboard class when we're in a movies and tv classification\n * because we don't want the extra padding between widgets.\n */\n return (\n <div className={`bg-white px-4 ${useLargeDashboardSpacing() ? 'dashboard-spacing-lg' : ''}`}>\n <BannerHeader\n heading={props.classification.name}\n banner={props.classification.banner}\n imageCdnUrl={props.imageCdnUrl}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n specialEvent={props.specialEvent}\n calendarTheme={{\n background: 'bg-light-blue',\n border: 'border-light-blue'\n }}\n showComingSoon={props.isComingSoon}\n detailsComponent={shouldShowTopicCounts\n ? () => <ClassificationHeaderDetails classification={props.classification} />\n : null\n }\n />\n\n <ClassificationDashboardNav\n dashboard={props.dashboard}\n classification={props.classification}\n presentation={props.presentation}\n appLinks={props.appLinks}\n activeTab={props.tab}\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n getBreadcrumbs={props.getBreadcrumbs}\n hasTopicDirectoryDashboard={props.hasTopicDirectoryDashboard}\n hasTopicCurriculumDashboard={props.hasTopicCurriculumDashboard}\n isComingSoon={props.isComingSoon}\n isEmpty={showEmptyState}\n isViewingCurrentPresentation={props.isViewCurrentPresentation}\n disableAudiences={isTopicOnlyDashboard || props.isReadonly}\n audienceTooltip={isTopicOnlyDashboard ? LanguageService.getPhrase(namespace, 'audienceTooltip') : ''}\n />\n\n {props.isComingSoon && (\n <ClassificationComingSoon\n imageUrl={props.comingSoonImageUrl}\n data={props.classification}\n canFollowSubjects={props.canFollowSubjects}\n showFollowButtonSpinner={props.showFollowButtonSpinner}\n onToggleFollow={() => props.onToggleFollow(props.classification, LocationContext.ClassificationComingSoon)}\n showSignUp={!props.hasLocalPermissions(LocalPermissionName.FollowComingSoonTopics)}\n signUpAppLink={props.appLinks.signUp?.()}\n />\n )}\n\n {!props.isComingSoon && (\n <div className={`${shouldShowSideTableOfContents ? 'row no-wrap' : ''}`}>\n {shouldShowTableOfContents && (\n <TableOfContentsContainer\n widgets={widgetsInTableOfContents}\n title={props.classification.name}\n activeId={tableOfContentActiveId}\n clickable={!props.isReadonly}\n analyticsData={props.analyticsData}\n setControlledId={setControlledId}\n isSmallScreen={isSmallScreen}\n />\n )}\n\n <div className={shouldShowSideTableOfContents ? 'col-9 order-0' : ''}>\n {widgets.map((widget, idx) => {\n if (hideWidget(widget))\n return <React.Fragment key={widget.id}></React.Fragment>;\n\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Classification}\n headingElementRef={headingRef}\n key={widget.id}\n id={widget.id}\n name={getWidgetHeading(widget, idx)}\n description={widget.description}\n classification={props.classification}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n audiences={props.audiences}\n getContentRequest={getWidgetContentRequest}\n setIsEmpty={onSetIsEmpty}\n appLinks={props.appLinks}\n presentation={props.presentation}\n analyticsData={props.analyticsData}\n isScrollToTargetWidget={props.scrollToWidgetId === widget.id}\n imageCdnUrl={props.imageCdnUrl}\n onSubmitFeedback={props.onSubmitFeedback}\n metadata={widget.metadata}\n isBot={props.isBot}\n hasTableOfContents={shouldShowSideTableOfContents}\n lazyLoad={props.lazyLoad}\n dashboardTarget={CuratedDashboardHelper.getDashboardTargetType(props.dashboard)}\n widgetIndex={idx}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n contentType={props.contentType}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n onToggleFollowClassification={props.onToggleFollow}\n settings={props.settings}\n isEditing={props.isReadonly}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n commonVideoProps={props.commonVideoProps}\n curriculums={props.curriculums}\n\n // TODO: Do we actually need this shit if it wasn't even being passed in?\n limitTotalItems={false}\n seeMoreLink={null}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n </div>\n\n {!!videoList?.length && (\n <>\n <WidgetHeader name={LanguageService.getPhrase(namespace, 'videos')} />\n <VideoList\n videos={videoList}\n getVideoAppLink={(video, opts) => props.appLinks.videoType(\n video,\n { ...opts, contextId: videoListWidgetId, includeContext: opts.includeContext }\n )}\n hasPermissions={props.hasPermissions}\n presentationAudiences={props.audiences}\n getPreviewQuestionsAppLink={props.appLinks.previewQuestions}\n commonVideoProps={props.commonVideoProps}\n />\n </>\n )}\n </div>\n )}\n\n {showEmptyState && (\n <CuratedClassificationEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.appLinks.widgetWizard}\n />\n )}\n\n {props.isTeacherOnly && (\n <TeacherOnlyEmptyState\n imageUrl={props.emptyImageUrl}\n ctaAppLink={() => props.appLinks.allTopics(props.classification.presentationId)}\n />\n )}\n </div>\n );\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { CuratedDashboard, CuratedMediaWidget, CuratedWidget, PresentationAudience, Video } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nexport interface Response {\n widgets: CuratedWidget[];\n\n videoList?: Video[];\n videoListWidgetId?: string;\n}\n\n/**\n * This hook helps us with custom logic for to display system generated dashboards in a slightly\n * different way.\n */\nexport function useGetTopicsWidgets(dashboard: CuratedDashboard, activeAudiences: PresentationAudience[]): Response {\n const {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget\n } = React.useMemo(() => {\n if (!dashboard) {\n return {\n isSystemGeneratedDashboard: false,\n systemGeneratedVideoWidget: null\n };\n }\n\n const isSystemGeneratedDashboard = CuratedDashboardHelper.isSystemGeneratedDashboard(dashboard.widgets);\n\n return {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget: dashboard.widgets.find(widget => {\n return (\n widget.widgetId === WidgetTypeId.ClassificationPinnedVideos &&\n widget.templateId !== WidgetTemplate.ThumbnailVerticalList\n );\n })\n };\n }, [dashboard?.id]);\n\n const systemGeneratedVideoContent = Flight.useBasicFetch<CuratedMediaWidget<Video[]>>(\n !!systemGeneratedVideoWidget &&\n DashboardRequests.dashboardWidgetContent(\n systemGeneratedVideoWidget?.id,\n CuratedDashboardHelper.getWidgetParams(\n systemGeneratedVideoWidget.widgetId,\n systemGeneratedVideoWidget.templateId,\n CuratedDashboardHelper.getDashboardTargetType(dashboard),\n activeAudiences?.map(a => a.masterId)\n ),\n systemGeneratedVideoWidget?.templateId\n )\n );\n\n // Non system generated dashboards are returned as per usual\n if (!isSystemGeneratedDashboard)\n return { widgets: ArrayHelper.sortBy(dashboard?.widgets, 'index') };\n\n // System generated dashboard have the video widget removed and returned as a separate video list\n return {\n widgets: dashboard?.widgets?.filter(widget => {\n if (widget.widgetId !== WidgetTypeId.ClassificationPinnedVideos)\n return true;\n\n if (widget.templateId === WidgetTemplate.ThumbnailVerticalList)\n return true;\n\n return false;\n }) ?? [],\n videoList: systemGeneratedVideoContent.data?.content ?? [],\n videoListWidgetId: systemGeneratedVideoWidget?.id\n };\n}","import React from 'react';\n\nimport { PartialAudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { PartialBreadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\n\nexport function PartialClassificationDashboard(): JSX.Element {\n return (\n <div className='bg-white px-4'>\n <PartialBannerHeader />\n\n <div className='d-flex flex-column row-gap-3 py-3 mb-3 border-bottom'>\n <PartialBreadcrumbs />\n <PartialAudienceFilter />\n </div>\n </div>\n );\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nconst endpoints = {\n follow: () => `{gateway}/v1/users/me/classifications/following`,\n unfollow: (ids: string[]) => UrlHelper.urlBuilder('{gateway}/v1/users/me/classifications/following', { id: ids })\n};\n\nexport const FollowRequests = {\n /**\n * @param data - array of object ids the user is going to follow\n */\n follow(\n ids: string[],\n userId: string,\n success?: (data: string[]) => void,\n error?: () => void\n ): Flight.Request {\n return {\n url: endpoints.follow(),\n key: `follow:${ids.join(',')}`,\n type: HttpVerbs.POST,\n data: ids,\n formatData: () => {\n return ids.map(id => ({\n id,\n followers: {\n data: [userId]\n }\n }));\n },\n success,\n error,\n invalidationKeys: [ ...ids.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications' ]\n };\n },\n\n unfollow(ids: string[], userId: string, success?: () => void, error?: () => void): Flight.Request {\n return {\n url: endpoints.unfollow(ids),\n key: `unfollow:${ids.join(',')}`,\n type: HttpVerbs.DELETE,\n formatData: () => {\n return ids.map(id => ({\n id,\n followers: {\n data: []\n }\n }));\n },\n success,\n error,\n invalidationKeys: [ ...ids.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications' ]\n };\n }\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ErrorCta, ErrorPageError } from 'libs/shared/errors/primitives/ErrorPageError';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'subjects.topicNotFoundError';\n\nexport class TopicNotFoundError extends ErrorPageError {\n constructor() {\n super('Topic doesn\\'t exist');\n }\n\n // @ts-ignore\n public get name(): string {\n return 'TopicNotFoundError';\n }\n\n // @ts-ignore\n public get heading(): string {\n return LanguageService.getPhrase(namespace, 'heading');\n }\n\n // @ts-ignore\n public get description(): string {\n return LanguageService.getPhrase(namespace, 'description');\n }\n\n // @ts-ignore\n public get cta(): ErrorCta {\n return {\n text: LanguageService.getPhrase(namespace, 'cta'),\n appLink: {\n application: AppChannels.SUBJECT,\n action: Actions.Subjects.PRESENTATION_TOPICS\n }\n };\n }\n}","// extracted by mini-css-extract-plugin\nexport default {\"followButton\":\"HlRXj\"};","import React from 'react';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, ToggleDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { CalendarRequests } from 'libs/shared/apps/calendar/flight-request/CalendarRequests';\nimport { LibraryHelper } from 'libs/shared/apps/libraries/utils/LibraryHelper';\nimport { ClassificationDashboard } from 'libs/shared/apps/subjects/components/classification-dashboard/ClassificationDashboard';\nimport { PartialClassificationDashboard } from 'libs/shared/apps/subjects/components/classification-dashboard/partial-loading/PartialClassificationDashboard';\nimport { PreviewBanner } from 'libs/shared/apps/subjects/components/preview-banner/PreviewBanner';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { ClassificationStatus } from 'libs/shared/enums/ClassificationStatus';\nimport { FeedbackType } from 'libs/shared/enums/FeedbackType';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { FeedbackRequests } from 'libs/shared/flight-requests/FeedbackRequests';\nimport { FollowRequests } from 'libs/shared/flight-requests/FollowRequests';\nimport { LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useBreadcrumbs } from 'libs/shared/hooks/useBreadcrumbs';\nimport { useCurationStudio } from 'libs/shared/hooks/useCurationStudio';\nimport { useHandleObjectError } from 'libs/shared/hooks/UseHandleObjectError';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { CalendarEvent, Classification, Config, CuratedWidgetQueryParams, CurrentUser, Customer, DashboardTargetType, Library, Presentation, PresentationAudience, RegionAlternative } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { FeedbackFormHelper } from 'libs/shared/utils/FeedbackFormHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { usePresentation } from 'shared/hooks/usePresentation';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\n\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { SignUpHelper } from 'apps/sign-up/utils/SignUpHelper';\nimport { TopicNotFoundError } from 'apps/subjects/errors/TopicNotFoundError';\nimport { useFetchClassificationDashboard } from 'apps/subjects/hooks/useFetchClassificationDashboard';\n\nimport { ClassificationViewQueryParams, getClassificationAppLinks } from './ClassificationViewUtils';\n\nimport styles from './curated-classification-view.scss';\n\ninterface CuratedClassificationViewProps {\n id: string;\n queryParams?: ClassificationViewQueryParams;\n targetType: DashboardTargetType;\n}\n\nCuratedClassificationView.defaultProps = {\n queryParams: {}\n};\n\nconst namespace = 'subjects.classification';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function CuratedClassificationView(props: CuratedClassificationViewProps): React.ReactElement {\n const [ showFollowButtonSpinner, setShowFollowButtonSpinner ] = React.useState<boolean>(false);\n\n const alerts = useAlerts();\n const fetchAsync = Flight.useGetFetchAsync();\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n const settings = useSettings(null);\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { openInCurationStudioLabel, isUserCurator, getOpenInCurationStudioLink } = useCurationStudio();\n const curriculums = useCurriculums();\n\n const customer = Flight.useBasicFetch<Customer>(\n hasPermissions(PermissionName.CanSubmitFeedback) &&\n currentUser.data?.isAuthenticated &&\n CustomerRequests.customer(currentUser.data.customerId)\n );\n\n const classification = Flight.useBasicFetch<Classification>(\n ClassificationRequests.classification(props.id, currentUser.data?.id)\n );\n\n const presentation = Flight.useBasicFetch<Presentation>(\n classification.data &&\n ClassificationRequests.presentationById(classification.data.presentationId)\n );\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n classification.data &&\n AudienceRequests.audiencesByPresentationId(classification.data.presentationId)\n );\n\n const specialEvent = Flight.useBasicFetch<CalendarEvent>(\n classification.data &&\n CalendarRequests.nextTopicSpecialEvent(props.id, classification.data.presentationId)\n );\n\n const libraries = Flight.useBasicFetch<Library[]>(\n currentUser.data?.isAuthenticated &&\n LibraryRequests.libraries()\n );\n\n const {\n activePresentation,\n availablePresentations,\n canAccessPresentation\n } = usePresentation();\n\n const path = Flight.useBasicFetch<Classification[]>(ClassificationRequests.path(props.id));\n\n const {\n dashboard,\n hasTopicDirectoryDashboard,\n hasTopicCurriculumDashboard,\n isPreviewing,\n isTeacherOnly\n } = useFetchClassificationDashboard(props.id, props.queryParams, props.targetType);\n\n const isTertiary = useIsTertiary();\n const products = useProducts();\n\n const regionAlternatives = Flight.useBasicFetch<RegionAlternative[]>(\n ClassificationRequests.regionAlternatives(props.id)\n );\n\n const preferredRegionAlternative = SeoHelper.getPreferredRegionAlternative(\n regionAlternatives.data,\n currentUser.data?.contentRegion\n );\n useSetPageMetadata(PageMetadataHelper.getClassificationMetadata({\n content: { classification: classification.data, dashboard: dashboard.data },\n\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n canonicalLink: SeoHelper.getCanonicalLink({\n stripPresentationSlug: true,\n customAppLink: ClassificationAppLinkHelper.getAppLink({\n ...classification.data,\n name: preferredRegionAlternative?.name || classification.data?.name\n }, props.queryParams),\n hrefTransformer: SeoHelper.createRegionHrefTransformer(\n regionAlternatives.data,\n currentUser.data?.contentRegion\n )\n }),\n allowIndexing: SeoHelper.allowIndexing(),\n hrefLang: SeoHelper.getContentHrefLang(regionAlternatives.data, () => (\n ClassificationAppLinkHelper.getAppLink(classification.data)\n ))\n }));\n\n useHandleObjectError(classification, {\n notFound: TopicNotFoundError\n });\n useDeepLinks({ id: props.id, app: 'topics' });\n\n const isViewCurrentPresentation = activePresentation?.id === presentation.data?.id;\n \n const isSmallScreen = useMediaQuery(MediaQueryStrings.MDDown);\n const isMobile = useMediaQuery(MediaQueryStrings.SMDown);\n\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.VideoThumbnail,\n mtv: props.queryParams.mtv\n });\n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem });\n\n const canFollowSubjects = hasPermissions(PermissionName.FollowSubjects);\n const isComingSoon = (\n classification.data?.status === ClassificationStatus.ComingSoon &&\n !isPreviewing\n );\n\n /**\n * We use the current active audiences to re-fetch content for that specific audience set.\n */\n const activeAudiences = AudienceHelper.getActiveAudiencesFromParams(audiences.data, props.queryParams);\n const activeAudienceIds = activeAudiences?.map(a => a.masterId) ?? [];\n\n const targetType = CuratedDashboardHelper.getDashboardTargetType(dashboard.data);\n\n /**\n * Following\n */\n function onToggleFollow(followedClassification: Classification, location: LocationContext) {\n if (!canFollowSubjects || !classification)\n return;\n\n const isTogglingCurrentTopic = followedClassification.id.toString() === classification.data?.id?.toString();\n\n if (isTogglingCurrentTopic)\n setShowFollowButtonSpinner(true);\n\n const isFollowing = TopicsHelper.isFollowing(followedClassification);\n\n const request = isFollowing\n ? FollowRequests.unfollow\n : FollowRequests.follow;\n\n fetchAsync(request([followedClassification.id], currentUser.data?.id))\n .then(() => {\n AnalyticsHelper.logUserAction(analyticsData, {\n location,\n actionType: UserAction.Follow,\n workflowPhase: WorkflowPhase.Complete,\n descriptor: isFollowing ? ToggleDescriptor.Off : ToggleDescriptor.On,\n entity: EntityType.Classification\n });\n\n if (!isTogglingCurrentTopic) {\n alerts.success(getPhrase(isFollowing ? 'unfollowed' : 'followed', { name: followedClassification.name }));\n }\n })\n .finally(() => {\n if (isTogglingCurrentTopic)\n setShowFollowButtonSpinner(false);\n });\n }\n\n async function onSubmitFeedback(feedback: DashboardFeedbackData): Promise<void> {\n const promise = await fetchAsync<void>(FeedbackRequests.submitFeedback({\n type: FeedbackType.Footer,\n user: FeedbackFormHelper.getUserInfo(currentUser.data, customer.data),\n tags: FeedbackFormHelper.getTags(\n currentUser.data,\n ProductId.Primary,\n hasPermissions(PermissionName.StudentExperience),\n [ 'topics', 'in product feedback' ]\n )\n }, {\n reaction: feedback.type,\n feedback: feedback.content,\n location: 'Topic Footer',\n presentationName: presentation.data.description,\n presentationId: presentation.data.id,\n dashboardName: dashboard.data.name,\n dashboardId: dashboard.data.id,\n classificationName: classification.data.name,\n classificationId: classification.data.id,\n currentPageUrl: LocationUtils.GetCurrentUrl()\n }));\n\n AnalyticsHelper.logUserAction({\n feedbackType: feedback.type,\n content: feedback.content,\n presentationId: presentation.data.id,\n classificationId: classification.data.id,\n dashboardId: dashboard.data.id\n }, {\n actionType: UserAction.Submit,\n location: LocationContext.ClassificationFooter,\n entity: EntityType.Feedback,\n workflowPhase: WorkflowPhase.Complete\n });\n\n return promise;\n }\n\n function getBannerActions(): ActionOptions[] {\n const isFollowing = !!classification.data?.followers?.data?.length;\n\n if (!canFollowSubjects)\n return [];\n\n const actions: ActionOptions[] = [{\n label: isMobile ? '' : getPhrase(isFollowing ? 'following' : 'follow'),\n onClick: () => onToggleFollow(classification.data, LocationContext.Banner),\n svgName: isFollowing ? cvSvgLibrary.BellFilled : cvSvgLibrary.Bell,\n className: `btn follow-btn me-2 ${isFollowing ? 'btn-outline-dark' : 'btn-dark'} ${styles.followButton}`,\n button: true,\n tooltip: (isFollowing || isSmallScreen) ? undefined : getPhrase('followBtnTooltip'),\n showSpinner: showFollowButtonSpinner\n }];\n\n if (isUserCurator)\n actions.push({\n label: openInCurationStudioLabel,\n href: getOpenInCurationStudioLink(MasterType.Subject, classification.data?.id, presentation.data?.id),\n openInNewTab: true\n });\n \n return actions;\n }\n\n const appLinks = getClassificationAppLinks(\n classification.data,\n targetType,\n props.queryParams,\n currentUser.data\n );\n\n const breadcrumbs = useBreadcrumbs({ name: classification.data?.name });\n function getBreadcrumbs(): () => Breadcrumb[] {\n if (!canAccessPresentation(presentation.data?.id))\n return;\n\n return () => breadcrumbs;\n }\n \n /**\n * Additional topics data to be mixed in with lower-level component analytics collection\n */\n const analyticsData = {\n presentationId: presentation.data?.id,\n presentationName: presentation.data?.name,\n currentClassificationId: classification.data?.id,\n currentClassificationName: classification.data?.name,\n followingCurrentClassification: !!classification.data?.followers?.data?.length,\n activeAudienceNames: activeAudiences?.length ? activeAudiences.map(a => a.name) : null,\n activeAudienceIds: activeAudienceIds.length ? activeAudienceIds : null\n };\n\n const dataLoaded = !!config.data\n && dashboard.hasCompleted\n && !!classification.data\n && !!presentation.data\n && !!path.data\n && !!availablePresentations\n && !!audiences.data\n && specialEvent.hasCompleted;\n\n if (!dataLoaded)\n return <PartialClassificationDashboard />;\n\n return (\n <VideoActionsContext.Provider value={videoActions}>\n <div className='position-relative'>\n {!!(isPreviewing && dashboard.data) && <PreviewBanner status={dashboard.data.status} type='topic' />}\n <ClassificationDashboard\n dashboard={dashboard.data}\n classification={classification.data}\n getWidgetContentRequest={(\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => {\n const { hasTwig, hasTigtag } = LibraryHelper.hasTwigOrTigtag(libraries.data, currentUser.data);\n \n return DashboardRequests.dashboardWidgetContent(\n id,\n params,\n widgetTemplate,\n presentation.data,\n { hideTigTag: !hasTigtag, hideTwig: !hasTwig }\n );\n }}\n getBreadcrumbs={getBreadcrumbs()}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n presentation={presentation.data}\n curriculums={curriculums}\n onToggleFollow={onToggleFollow}\n getBannerActions={getBannerActions}\n audiences={props.queryParams.mtv ? null : audiences.data}\n activeAudiences={activeAudiences}\n analyticsData={analyticsData}\n imageCdnUrl={config.data.imageCdnUrl}\n resourceThumbnailFallbackImageUrl={ImageUrls.Fallbacks.RESOURCE_THUMBNAIL}\n emptyImageUrl={isTeacherOnly ? ImageUrls.EmptyStates.Topics.TEACHER_ONLY : ImageUrls.EmptyStates.Topics.TOPIC}\n isComingSoon={isComingSoon}\n showFollowButtonSpinner={showFollowButtonSpinner}\n comingSoonImageUrl={ImageUrls.EmptyStates.Topics.COMING_SOON}\n appLinks={{\n ...appLinks,\n signUp: SignUpHelper.getSignUpAppLink,\n widgetWizard: () => null,\n previewQuestions: interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive)\n }}\n isPreviewing={isPreviewing}\n isViewCurrentPresentation={isViewCurrentPresentation}\n canFollowSubjects={canFollowSubjects}\n onSubmitFeedback={\n hasPermissions(PermissionName.CanSubmitFeedback) &&\n onSubmitFeedback\n }\n tableOfContentsId={props.queryParams.tocId}\n lazyLoad={!SeoHelper.isBot()}\n moviesAndTv={props.queryParams.mtv}\n isTeacherOnly={isTeacherOnly}\n specialEvent={specialEvent.data}\n isBot={SeoHelper.isBot()}\n hasTopicDirectoryDashboard={hasTopicDirectoryDashboard}\n hasTopicCurriculumDashboard={hasTopicCurriculumDashboard}\n tab={TopicsHelper.getActiveTopicTab(classification.data, props.targetType)}\n // just... one... more.. prop....\n settings={settings}\n isTertiaryCustomerWithoutExchange={isTertiary && !products?.hasProduct(ProductId.Exchange)}\n commonVideoProps={commonVideoProps}\n />\n </div>\n </VideoActionsContext.Provider>\n );\n}\n","import { useSettings } from 'libs/shared/hooks/useSettings';\nimport { DashboardTargetType } from 'libs/shared/interfaces';\n\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\n\nimport { ClassificationViewQueryParams } from '../views/classification/ClassificationViewUtils';\n\nexport function useFetchClassificationDashboard(\n id: string,\n queryParams: ClassificationViewQueryParams,\n targetType: DashboardTargetType\n) {\n const { hasTopicDirectories, hasTopicVideoListFeature } = useSettings(null);\n\n const {\n dashboard: curatedTopicDashboard,\n isPreviewing,\n isTeacherOnly\n } = useFetchCuratedDashboard({\n classificationId: id,\n queryParams: queryParams,\n targetType: DashboardTargetType.Classification\n });\n\n const { dashboard: directoryDashboard } = useFetchCuratedDashboard({\n classificationId: id,\n queryParams: queryParams,\n targetType: DashboardTargetType.ClassificationDirectory\n });\n\n const { dashboard: curriculumDashboard } = useFetchCuratedDashboard({\n classificationId: id,\n queryParams: queryParams,\n targetType: DashboardTargetType.ClassificationCurriculum\n });\n\n function getDashboard() {\n switch (targetType) {\n case DashboardTargetType.Classification:\n return curatedTopicDashboard;\n case DashboardTargetType.ClassificationDirectory:\n return directoryDashboard;\n case DashboardTargetType.ClassificationCurriculum:\n return curriculumDashboard;\n }\n }\n\n return {\n dashboard: getDashboard(),\n hasTopicDirectoryDashboard: hasTopicDirectories && !!directoryDashboard.data,\n hasTopicCurriculumDashboard: hasTopicVideoListFeature && !!curriculumDashboard.data,\n isTeacherOnly,\n isPreviewing\n };\n}","// extracted by mini-css-extract-plugin\nexport default {\"pillTabSelector\":\"Hdi6o\",\"tab\":\"RvNxr\",\"minWidth\":\"GHSz9\",\"radiusSmall\":\"VhJJa\",\"tabLink\":\"WFyvo\"};"],"names":["CalendarRequests","calendarEvents","from","to","presentationId","url","publicUrl","key","nextTopicSpecialEvent","classificationId","params","limit","Date","objectType","formatData","events","getPhrase","LanguageService","AudienceItem","props","audience","highlight","setAudience","isDisabled","extraClasses","colourClass","getColourClass","cursorClass","className","type","onClick","FunctionHelper","role","name","disabled","split","map","s","charAt","toUpperCase","substring","join","defaultProps","DashboardStatusConfig","Dashboard","svgName","svgColorClassName","actionName","statusName","getClassName","status","darkMode","wrapperClassName","DashboardStatusBadge","SvgContainer","PreviewBanner","EmojiText","emoji","namespace","BackButton","textShadow","backToName","appLink","color","backPhrase","colorClass","textShadowClass","AppLink","size","S","RATIO","width","height","getSizeClass","heading","length","BannerHeader","banner","imageCdnUrl","actions","sortComponent","blockColourClass","specialEvent","portalContainerContext","BannerPortalContext","imageWidth","useBreakpoints","xxl","specialEventIsToday","showComingSoon","today","DateHelper","endDate","startDate","imageOptions","ratio","resizeType","ImageHelper","fallbackBaseUrl","fallbackCategoryName","containerProps","bannerClassName","style","backgroundImage","DetailsComponent","detailsComponent","logoFallbackBgClassName","getBgColorClass","PortalHelper","backButtonAppLink","backButtonText","backButtonClasses","alignLogoLeft","logo","GenericCalendarDate","body","text","month","getSpecialEventMonthText","theme","calendarTheme","Text","phrase","ComingSoonTag","LazyImage","src","backgroundColor","logoBgColour","Actions","actionsDropdownClassName","container","prevProps","nextProps","PartialBannerHeader","TabContents","tab","count","data","PillTabSelector","ref","containerRef","borderRadius","listClassName","tabs","index","active","analyticsData","analyticsOptions","onSelect","onSelectTab","FeedbackType","defaultErrors","notFound","forbidden","rating","yearLevel","region","privacy","badRequest","internalServerError","handleHttpError","info","customErrorMap","ignoreMap","statusCode","errorMap","FeedbackRequests","submitFeedback","requestData","formValues","generateCacheKey","flightObjs","obj","useHandleObjectError","_flightObjs","customErrors","ignoreErrors","Array","isArray","useEffect","forEach","useBreadcrumbs","current","match","breadcrumbs","useBuilder","COUNTRY_CODE_TAGS","C","FeedbackFormHelper","getUserInfo","currentUser","customer","id","username","email","userType","customerId","cvcId","crmId","customerName","instanceRegion","contentRegion","firstName","givenName","lastName","familyName","mapCountryCodeToTag","countryCode","toLowerCase","getTags","product","hasStudentExperience","extraTags","tags","push","countryCodeTag","categorizeFiles","files","reduce","result","file","fileInfo","get","videoUrls","imageUrls","Separator","ClassificationHeaderDetails","TopicsHelper","classification","dashboardVideoCount","childDashboardVideoCount","dashboardResourceCount","childDashboardResourceCount","childClassificationCount","videoCount","resourceCount","options","toLocaleString","smartCount","CuratedClassificationEmptyState","isArchived","dashboard","value","EmptyState","imageUrl","altText","isReadonly","Tooltip","title","spanHack","addWidgetApplink","icon","TableOfContentsMobile","isExpanded","setIsExpanded","TableOfContentsList","items","widgets","widget","tocIndentation","metadata","activeId","setControlledId","getAppLink","onItemClick","IconButton","actionType","entity","location","AnalyticsHelper","TableOfContents","TableOfContentsContainer","currentAppLink","ContextService","tocId","isSmallScreen","TeacherOnlyEmptyState","ctaAppLink","ClassificationComingSoon","isFollowing","followers","showSignUp","canFollowSubjects","ActionButton","onToggleFollow","showSpinner","showFollowButtonSpinner","signUpAppLink","workflowPhase","descriptor","SignUp","tag","AudienceFilter","audiences","activeAudiences","setActiveAudiences","SharedViewModelKeys","undefined","storage","onToggleAudience","isSelected","otherParams","activeAudienceNames","a","filter","ObjectHelper","Object","assign","replace","disablePersist","tooltip","masterId","find","aa","keys","DivButton","PARTIAL_AUDIENCES","PartialLoadingHelper","numItems","PartialAudienceFilter","idx","dangerouslySetInnerHTML","__html","ClassificationDashboardAudiences","getTabs","breakpoints","activeTab","isHighlighting","showText","lg","xl","xs","appLinks","classificationName","presentation","presentationDescription","description","classificationDirectory","classificationCurriculum","ClassificationTabs","useDirectoryTabProductTipSwitcher","setProductTipRef","el","ClassificationDashboardNav","isEmpty","hideAudiences","isComingSoon","AudienceHelper","canShowTabs","hasTopicDirectoryDashboard","externalMetadata","isCurated","hasTopicCurriculumDashboard","getTopRowClass","Breadcrumbs","getBreadcrumbs","getBottomRowClass","disableAudiences","audienceTooltip","isViewingCurrentPresentation","isHeadingWidget","widgetId","WidgetTypeId","templateId","WidgetTemplate","isTopicWidget","ClassificationDashboard","isSystemGeneratedDashboard","systemGeneratedVideoWidget","systemGeneratedVideoContent","DashboardRequests","videoList","content","videoListWidgetId","ArrayHelper","useGetTopicsWidgets","headingRef","Set","initialEmptyWidgets","acc","emptyWidgets","setEmptyWidgets","tableOfContentsId","controlledId","tableOfContentActiveId","setTableOfContentActiveId","headingElements","getWidgetContentRequest","widgetTypeId","template","curriculums","preferredCurriculum","useTableOfContentsScroll","useTableOfContentsActiveHeading","setActiveId","showEmptyState","isTeacherOnly","isPreviewing","values","every","state","onSetIsEmpty","newEmptyState","currentWidget","isHeadingEmpty","subWidgetIndex","headingSubWidget","hideWidget","getWidgetHeading","previousWidget","target","widgetsInTableOfContents","w","showInTableOfContents","isTopicOnlyDashboard","shouldShowTableOfContents","shouldShowSideTableOfContents","shouldShowTopicCounts","settings","hasTopicDirectories","isTertiaryCustomerWithoutExchange","moviesAndTv","getBannerActions","background","border","isViewCurrentPresentation","comingSoonImageUrl","hasLocalPermissions","signUp","clickable","WidgetContainerView","widgetCollection","headingElementRef","getContentRequest","setIsEmpty","isScrollToTargetWidget","scrollToWidgetId","onSubmitFeedback","isBot","hasTableOfContents","lazyLoad","dashboardTarget","widgetIndex","hasPermissions","contentType","resourceThumbnailFallbackImageUrl","onToggleFollowClassification","isEditing","commonVideoProps","limitTotalItems","seeMoreLink","onClickRemoveItem","badgeComponent","WidgetHeader","VideoList","videos","getVideoAppLink","video","opts","videoType","contextId","includeContext","presentationAudiences","getPreviewQuestionsAppLink","previewQuestions","emptyImageUrl","widgetWizard","allTopics","PartialClassificationDashboard","endpoints","ids","UrlHelper","FollowRequests","follow","userId","success","error","HttpVerbs","invalidationKeys","unfollow","TopicNotFoundError","application","action","ErrorPageError","CuratedClassificationView","queryParams","setShowFollowButtonSpinner","alerts","fetchAsync","usePermissions","useSettings","config","ConfigRequests","UserRequests","useCurationStudio","openInCurationStudioLabel","isUserCurator","getOpenInCurationStudioLink","useCurriculums","PermissionName","isAuthenticated","CustomerRequests","ClassificationRequests","AudienceRequests","libraries","LibraryRequests","usePresentation","activePresentation","availablePresentations","canAccessPresentation","path","targetType","hasTopicVideoListFeature","curatedTopicDashboard","directoryDashboard","curriculumDashboard","getDashboard","useFetchClassificationDashboard","isTertiary","useIsTertiary","products","regionAlternatives","preferredRegionAlternative","SeoHelper","useSetPageMetadata","PageMetadataHelper","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","canonicalLink","stripPresentationSlug","customAppLink","ClassificationAppLinkHelper","hrefTransformer","allowIndexing","hrefLang","useDeepLinks","app","isMobile","useCommonVideoProps","locationContext","mtv","videoActions","useVideoActions","ClassificationStatus","activeAudienceIds","followedClassification","isTogglingCurrentTopic","toString","request","then","presentationName","currentClassificationId","currentClassificationName","followingCurrentClassification","hasCompleted","VideoActionsContext","widgetTemplate","LibraryHelper","hasTwig","hasTigtag","hideTigTag","hideTwig","label","button","href","MasterType","openInNewTab","ImageUrls","SignUpHelper","interactive","InteractiveHelper","feedback","user","ProductId","reaction","dashboardName","dashboardId","currentPageUrl","promise","feedbackType","hasProduct"],"sourceRoot":""}
1
+ {"version":3,"file":"scripts/6948-b1b7f560c9-lite.chunk.js","mappings":"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","sources":["file:///app/packages/libs/shared/src/apps/calendar/flight-request/CalendarRequests.ts","file:///app/packages/libs/shared/src/apps/subjects/components/audience-item/audience-item.scss","file:///app/packages/libs/shared/src/apps/subjects/components/audience-item/AudienceItem.tsx","file:///app/packages/libs/shared/src/apps/subjects/constants/DashboardStatusConfig.ts","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/dashboard-status-badge.scss","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/preview-banner/preview-banner.scss","file:///app/packages/libs/shared/src/apps/subjects/components/preview-banner/PreviewBanner.tsx","file:///app/packages/libs/shared/src/components/back-button/BackButton.tsx","file:///app/packages/libs/shared/src/components/banner-header/banner-header.scss","file:///app/packages/libs/shared/src/components/banner-header/BannerHeader.tsx","file:///app/packages/libs/shared/src/components/pill-tab-selector/PillTabSelector.tsx","file:///app/packages/libs/shared/src/enums/FeedbackType.ts","file:///app/packages/libs/shared/src/errors/handlers/HttpErrorHandlers.ts","file:///app/packages/libs/shared/src/flight-requests/FeedbackRequests.ts","file:///app/packages/libs/shared/src/hooks/UseHandleObjectError.ts","file:///app/packages/libs/shared/src/hooks/useBreadcrumbs.ts","file:///app/packages/libs/shared/src/utils/FeedbackFormHelper.ts","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/table-of-contents.scss","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-coming-soon/ClassificationComingSoon.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/audience-filter/AudienceFilter.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/audiences/ClassificationDashboardAudiences.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/classification-tabs.scss","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/ClassificationTabs.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/classification-dashboard-nav/ClassificationDashboardNav.tsx","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/ClassificationDashboard.tsx","file:///app/packages/libs/shared/src/apps/subjects/hooks/useGetTopicsWidgets.ts","file:///app/packages/libs/shared/src/apps/subjects/components/classification-dashboard/partial-loading/PartialClassificationDashboard.tsx","file:///app/packages/libs/shared/src/flight-requests/FollowRequests.ts","file:///app/packages/projects/lite/src/apps/subjects/errors/TopicNotFoundError.ts","file:///app/packages/projects/lite/src/apps/subjects/views/classification/curated-classification-view.scss","file:///app/packages/projects/lite/src/apps/subjects/views/classification/CuratedClassificationView.tsx","file:///app/packages/projects/lite/src/apps/subjects/hooks/useFetchClassificationDashboard.ts","file:///app/packages/libs/shared/src/components/pill-tab-selector/pill-tab-selector.scss"],"sourcesContent":["import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { CalendarEvent, CalendarEventContentType } from 'libs/shared/interfaces';\n\nexport const CalendarRequests = {\n calendarEvents(\n from: string,\n to: string,\n presentationId: string\n ): Flight.PublicRequest {\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/discover/special-events/content', { from, to, presentationId }),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/special-events/content`, { from, to, presentationId }),\n key: `presentation:${presentationId}:events:from:${from}:to${to}`\n };\n },\n\n nextTopicSpecialEvent(\n classificationId: string,\n presentationId: string\n ): Flight.PublicRequest {\n const params = {\n presentationId,\n limit: 1,\n from: DateHelper.format(new Date(), 'YYYY-MM-DD'),\n objectType: CalendarEventContentType.Classification\n };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/special-events/object/${classificationId}/next-events`, params),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/special-events/object/${classificationId}/next-events`, params),\n key: `presentation:${presentationId}:events:classification:${classificationId}`,\n formatData: (events: CalendarEvent[]) => ArrayHelper.first(events)\n };\n }\n};\n","// extracted by mini-css-extract-plugin\nexport default {\"disabled\":\"pERi4\",\"disabledHighlighted\":\"AxyWm\",\"badge\":\"KmfP8\"};","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport styles from './audience-item.scss';\n\nconst namespace = 'shared.audienceItem';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction lowerCaseToTitleCase(str: string): string {\n return str.split(' ').map((s: string) => s.charAt(0).toUpperCase() + s.substring(1)).join(' ');\n}\n\nfunction getColourClass(highlight: boolean, isDisabled: boolean): string {\n if (highlight) return isDisabled ? `${styles.disabledHighlighted} text-light` : 'bg-gray-900 text-light';\n if (isDisabled) return `${styles.disabled} text-secondary`;\n return 'bg-light';\n}\n\ninterface AudienceItemProps {\n audience: PresentationAudience;\n highlight: boolean;\n setAudience?: (audience: PresentationAudience, highlight: boolean) => void;\n isDisabled?: boolean;\n extraClasses?: string;\n}\n\nAudienceItem.defaultProps = {\n extraClasses: ''\n};\n\nexport function AudienceItem(props: AudienceItemProps): React.ReactElement {\n const { audience, highlight, setAudience, isDisabled, extraClasses } = props;\n\n const colourClass = getColourClass(highlight, isDisabled);\n const cursorClass = isDisabled ? 'cursor-default' : 'cursor-pointer';\n const className = `${styles.badge} lh-1 rounded-pill d-inline-block me-1 user-select-none ${cursorClass} ${colourClass} ${extraClasses}`;\n\n const onClick = () => {\n if (isDisabled || !FunctionHelper.isFunction(setAudience))\n return;\n\n setAudience(audience, !highlight);\n };\n\n return (\n <button\n type='button'\n className={className}\n onClick={onClick}\n role='checkbox'\n aria-checked={highlight}\n aria-label={`${getPhrase('ariaFilter')} ${audience.name}`}\n disabled={isDisabled}\n >\n {lowerCaseToTitleCase(audience.name)}\n </button>\n );\n}","import { localSvgs } from 'libs/shared/images/svg';\nimport { DashboardStatus } from 'libs/shared/interfaces/models/Dashboard';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\ninterface DashboardStatusConfigType {\n statusName: string;\n actionName: string;\n svgName: localSvgs;\n svgColorClassName: string;\n}\n\nexport const DashboardStatusConfig: Record<DashboardStatus, DashboardStatusConfigType> = {\n [DashboardStatus.Archived]: {\n svgName: cvSvgLibrary.Archive,\n svgColorClassName: 'text-secondary',\n actionName: 'Archive',\n statusName: 'Archived'\n },\n [DashboardStatus.Draft]: {\n svgName: cvSvgLibrary.Edit,\n svgColorClassName: '',\n actionName: 'Draft',\n statusName: 'Draft'\n },\n [DashboardStatus.Published]: {\n svgName: cvSvgLibrary.VisibleOn,\n svgColorClassName: 'text-success',\n actionName: 'Publish',\n statusName: 'Published'\n }\n};","// extracted by mini-css-extract-plugin\nexport default {\"badge\":\"ciO47\",\"draftLight\":\"A6Yi7\",\"draftDark\":\"fkXBX\",\"published\":\"Ovzwy\",\"archived\":\"r_dco\"};","import React from 'react';\n\nimport { DashboardStatusConfig } from 'libs/shared/apps/subjects/constants/DashboardStatusConfig';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { DashboardStatus } from 'libs/shared/interfaces';\n\nimport styles from './dashboard-status-badge.scss';\n\nfunction getClassName(props: DashboardStatusBadgeProps): string {\n let className = `rounded-pill d-flex align-items-center ps-2 py-1 fw-semibold ms-2 ${styles.badge}`;\n\n switch (props.status) {\n case DashboardStatus.Published:\n className += ` ${styles.published}`;\n break;\n case DashboardStatus.Archived:\n className += ` ${styles.archived}`;\n break;\n case DashboardStatus.Draft:\n className += ` ${props.darkMode ? styles.draftDark : styles.draftLight}`;\n break;\n }\n\n if (props.wrapperClassName)\n className += ` ${props.wrapperClassName}`;\n\n return className;\n}\n\ninterface DashboardStatusBadgeProps {\n status: DashboardStatus;\n darkMode?: boolean;\n wrapperClassName?: string;\n}\n\nexport function DashboardStatusBadge(props: DashboardStatusBadgeProps): JSX.Element {\n const { statusName, svgName } = DashboardStatusConfig[props.status];\n\n return (\n <div className={getClassName(props)}>\n <SvgContainer svgName={svgName} />\n <div>{statusName}</div>\n </div>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"stickyWrapper\":\"zhw6K\",\"badgeWrapper\":\"NOvn1\",\"badge\":\"pxQSR\"};","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { DashboardStatusBadge } from 'libs/shared/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge';\nimport { EmojiText } from 'libs/shared/components/emoji-text/EmojiText';\nimport { DashboardStatus } from 'libs/shared/interfaces';\n\nimport styles from './preview-banner.scss';\n\nconst namespace = 'shared.classificationPreviewBanner';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface PreviewBannerProps {\n status: DashboardStatus;\n type: 'company' | 'topic';\n}\n\nexport function PreviewBanner(props: PreviewBannerProps): JSX.Element {\n return (\n <div className={`${styles.stickyWrapper} py-2 d-flex justify-content-space-between bg-dark text-white mx-2 rounded`}>\n <div className={`position-absolute d-flex ${styles.badgeWrapper}`}>\n <DashboardStatusBadge status={props.status} wrapperClassName={`${styles.badge}`} darkMode />\n </div>\n <div className='flex-grow-1'>\n <h1 className='text-center my-3 h5'>\n <EmojiText emoji='👀' />\n {getPhrase(props.type === 'topic' ? 'topicTitle' : 'companyTitle')}\n </h1>\n </div>\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'shared.backButton';\n\ninterface BackButtonProps {\n appLink: Core.AppLink;\n backToName?: string;\n color?: 'black' | 'white';\n extraClasses?: string;\n /**\n * Whether or not the button text has a text shadow. Defaults to true\n */\n textShadow?: boolean;\n}\n\nBackButton.defaultProps = {\n color: 'black',\n extraClasses: ''\n};\n\nexport function BackButton(props: BackButtonProps): React.ReactElement {\n const { backToName, appLink, color, extraClasses, textShadow } = {\n textShadow: true,\n ...props\n };\n\n const backPhrase = backToName\n ? LanguageService.getPhrase(namespace, 'backTo', { backToName })\n : LanguageService.getPhrase(namespace, 'back');\n\n const colorClass = color === 'black' ? '' : 'text-white';\n const textShadowClass = textShadow ? 'text-shadow' : '';\n\n return (\n <AppLink\n appLink={appLink}\n className={`d-inline-flex align-items-center h5 mb-0 ${extraClasses} ${colorClass} ${textShadowClass}`}\n >\n <SvgContainer svgName={cvSvgLibrary.ChevronLeft} size={SvgContainerSize.Medium} />\n <span className='ms-1'>{backPhrase}</span>\n </AppLink>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"bannerContent\":\"sSCTB\",\"actionsContainer\":\"Z5WI2\",\"bannerContentWithLogo\":\"rgs7Q\",\"container\":\"M51HJ\",\"logoContainer\":\"vkeJk\",\"logoContainerLeft\":\"M3U9B\",\"logoHeading\":\"EtRwC\",\"specialEventContainer\":\"rOxDc\",\"headingLarge\":\"_8pnV\",\"heading\":\"JXVBH\"};","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ComingSoonTag } from 'libs/shared/apps/calendar/components/coming-soon-tag/ComingSoonTag';\nimport { GenericCalendarDate } from 'libs/shared/apps/calendar/components/generic-calendar-date/GenericCalendarDate';\nimport { CalendarTheme } from 'libs/shared/apps/calendar/interfaces/CalendarTheme';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { BackButton } from 'libs/shared/components/back-button/BackButton';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { ImageMinDimensions } from 'libs/shared/constants/ImageSizes';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ImageSize, ImageType, ResizeType } from 'libs/shared/enums/Images';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Banner, CalendarEvent, Logo } from 'libs/shared/interfaces';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport styles from './banner-header.scss';\n\nconst RATIO = `${ImageMinDimensions[ImageType.Banners].width}:${ImageMinDimensions[ImageType.Banners].height}`;\nconst DEFAULT_WIDTH = 1200; // This is ImageSize.Large for a Banner.\nconst LARGE_SCREEN_WIDTH = 1920;\n\nfunction useGetImageWidth(): number {\n const breakpoints = useBreakpoints();\n\n if (breakpoints.xxl)\n return LARGE_SCREEN_WIDTH;\n\n return DEFAULT_WIDTH;\n}\n\nfunction getSizeClass(heading: string): string {\n if (heading.length < 160)\n return 'h1';\n\n return styles.headingLarge;\n}\n\ninterface BannerHeaderProps {\n heading: string;\n banner?: Banner;\n bannerClassName?: string;\n imageCdnUrl?: string;\n logo?: Logo;\n logoBgColour?: string;\n actions?: ActionOptions[];\n specialEvent?: CalendarEvent;\n backButtonAppLink?: Core.AppLink;\n backButtonText?: string;\n backButtonClasses?: string;\n sortComponent?: JSX.Element;\n blockColourClass?: string;\n actionsDropdownClassName?: string;\n detailsComponent?: () => React.ReactElement;\n imageOptions?: ImageOptions;\n showComingSoon?: boolean;\n alignLogoLeft?: boolean;\n calendarTheme?: CalendarTheme;\n}\n\nconst namespace = 'shared.bannerHeader';\n\nexport const BannerHeader = React.memo(function(props: React.PropsWithChildren<BannerHeaderProps>): React.ReactElement {\n const { heading, banner, imageCdnUrl, actions, sortComponent, blockColourClass, specialEvent } = props;\n\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n const imageWidth = useGetImageWidth();\n\n const specialEventIsToday = React.useMemo(() => {\n if (!specialEvent || props.showComingSoon)\n return false;\n\n const today = DateHelper.format(new Date(), 'YYYY-MM-DD');\n\n if (!specialEvent.endDate)\n return specialEvent.startDate === today;\n\n return specialEvent.startDate <= today && specialEvent.endDate >= today;\n }, [specialEvent]);\n\n function getSpecialEventMonthText(specialEvent: CalendarEvent): string {\n if (!specialEvent.endDate)\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n if (DateHelper.isSame(specialEvent.startDate, specialEvent.endDate, 'month'))\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n return `${DateHelper.format(specialEvent.startDate, 'MMM')} - ${DateHelper.format(specialEvent.endDate, 'MMM')}`;\n }\n\n const imageOptions = props.imageOptions || {\n width: imageWidth,\n ratio: RATIO,\n resizeType: ResizeType.Cover\n };\n\n const url = !!banner && !!imageCdnUrl && ImageHelper.createBannerUrl(banner, {\n fallbackBaseUrl: imageCdnUrl,\n fallbackCategoryName: heading,\n type: ImageType.Banners\n }, imageOptions);\n\n const containerProps: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> = {\n className: `banner banner-header ${props.bannerClassName}`,\n style: url ? { backgroundImage: `url('${url}')` } : {}\n };\n\n if (!banner && blockColourClass) {\n delete containerProps.style;\n containerProps.className += ` ${blockColourClass}`;\n }\n\n const DetailsComponent = props.detailsComponent;\n\n const logoFallbackBgClassName = getBgColorClass(props.heading, BG_COLOUR_CLASS_NAMES);\n\n return PortalHelper.renderInPortalIfExists(\n // \"banner\" is used in playlists in Online. banner-header is used by all other projects\n <header {...containerProps}>\n <div className={`container ${styles.container} position-relative inner-banner`}>\n {props.backButtonAppLink && (\n <div className='pt-3'>\n <BackButton\n appLink={props.backButtonAppLink}\n backToName={props.backButtonText}\n extraClasses={props.backButtonClasses}\n color='white'\n />\n </div>\n )}\n \n <div className={`${props.alignLogoLeft ? 'position-absolute top-50 start-0 translate-middle-y w-100 ps-4' : `${styles.bannerContent} px-2 ${props.logo?.url ? styles.bannerContentWithLogo : ''}`}`}>\n {!!specialEvent && (\n <div className={`position-relative ${styles.specialEventContainer}`}>\n <GenericCalendarDate\n body={{\n type: specialEvent.endDate ? 'range' : 'day',\n text: specialEvent.endDate\n ? `${DateHelper.format(specialEvent.startDate, 'DD')}-${DateHelper.format(specialEvent.endDate, 'DD')}`\n : DateHelper.format(specialEvent.startDate, 'DD')\n }}\n month={getSpecialEventMonthText(specialEvent)}\n theme={props.calendarTheme}\n />\n </div>\n )}\n <div>\n {specialEventIsToday && (\n <div className='rounded-pill py-1 px-2 my-1 me-1 fw-semibold bg-light-blue lh-1 d-inline-block'>\n <Text namespace={namespace} phrase='onToday' />\n </div>\n )}\n {props.showComingSoon && (\n <ComingSoonTag className='pe-2 fw-semibold mb-1 rounded-pill justify-content-start text-nowrap' />\n )}\n <div className='d-flex align-items-center'>\n {props.alignLogoLeft && props.logo?.url &&\n <div className={`${styles.logoContainerLeft} d-none d-md-block rounded-circle overflow-hidden me-3 ${logoFallbackBgClassName}`}>\n <LazyImage\n src={ImageHelper.createUrl(props.logo?.url, { size: ImageSize.Medium })}\n style={{ backgroundColor: props.logoBgColour }}\n />\n </div>\n }\n <h1 className={`text-white text-shadow pe-3 position-static ${styles.heading} ${getSizeClass(heading)} ${props.alignLogoLeft ? 'w-50' : ''}`}>\n {heading}\n {DetailsComponent && <DetailsComponent />}\n </h1>\n </div>\n </div>\n {!!actions && (\n <div className={styles.actionsContainer}>\n <Actions\n actions={actions}\n sortComponent={sortComponent}\n actionsDropdownClassName={props.actionsDropdownClassName}\n />\n </div>\n )}\n </div>\n {!props.alignLogoLeft && !!props.logo?.url &&\n <div className={styles.logoContainer}>\n <img\n src={ImageHelper.createUrl(props.logo.url, { size: ImageSize.Medium })}\n className='rounded-circle'\n />\n </div>\n }\n </div>\n </header>,\n portalContainerContext?.container\n );\n}, (prevProps, nextProps): boolean => (\n prevProps.actions === nextProps.actions\n && prevProps.heading === nextProps.heading\n && prevProps.logo?.url === nextProps.logo?.url\n));\n\nexport function PartialBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className={`partial-banner partial-loading-background ${styles.banner}`} />,\n portalContainerContext?.container\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { Badge, BadgeType } from 'libs/shared/components/badges/Badge';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\n\nimport { SvgContainer } from '../svg-container/SvgContainer';\n\nimport styles from './pill-tab-selector.scss';\n\ninterface TabContentsProps {\n tab: PillTab;\n}\n\nfunction TabContents(props: TabContentsProps): JSX.Element {\n return (\n <>\n {!!props.tab.svgName && (\n <div className={props.tab.name ? 'pe-1' : ''}>\n <SvgContainer svgName={props.tab.svgName} />\n </div>\n )}\n\n {props.tab.name}\n\n {typeof (props.tab.count) === 'number' && (\n <div className='ps-2'>\n <Badge type={BadgeType.Count} data={props.tab.count} />\n </div>\n )}\n </>\n );\n}\n\nexport interface PillTab {\n name: string;\n active: boolean;\n svgName?: string;\n\n className?: string;\n\n appLink?: Core.AppLink;\n onSelect?: () => void;\n\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n\n count?: number;\n}\n\ninterface PillTabSelectorProps {\n tabs: PillTab[];\n containerRef?: (el: HTMLElement) => void;\n listClassName?: string;\n className?: string;\n borderRadius?: 'sm' | 'lg'\n}\n\nPillTabSelector.defaultProps = {\n borderRadius: 'lg'\n};\n\nexport function PillTabSelector(props: PillTabSelectorProps): JSX.Element {\n function onSelectTab(tab: PillTab): void {\n if (tab.active || !tab.onSelect)\n return;\n\n tab.onSelect();\n\n if (tab.analyticsData && tab.analyticsOptions)\n AnalyticsHelper.logUserAction(tab.analyticsData, tab.analyticsOptions);\n }\n\n return (\n <nav className={props.className ?? ''} ref={props.containerRef}>\n <ul className={`\n list-unstyled d-inline-block m-0 ${styles.pillTabSelector}\n ${props.borderRadius ? styles.radiusSmall : ''}\n ${props.listClassName}\n `}>\n {props.tabs.map((tab, index) => {\n return (\n <li\n className={`\n p-0 ${styles.tab} ${tab.active ? 'btn btn-dark' : 'btn btn-outline-dark'}\n ${tab.name ? styles.minWidth : ''} ${tab.className}\n `}\n key={index}\n >\n {tab.appLink ? (\n <AppLink\n appLink={tab.appLink}\n analyticsData={tab.analyticsData}\n analyticsOptions={tab.analyticsOptions}\n className={`\n cursor-pointer d-flex align-items-center justify-content-center\n text-decoration-none text-reset px-2 text-nowrap ${styles.tabLink}\n `}\n >\n <TabContents tab={tab} />\n </AppLink>\n ) : (\n <DivButton\n className={`\n cursor-pointer d-flex align-items-center justify-content-center\n text-decoration-none text-reset px-2 text-nowrap ${styles.tabLink}\n `}\n onClick={() => onSelectTab(tab)}\n >\n <TabContents tab={tab} />\n </DivButton>\n )}\n </li>\n );\n })}\n </ul>\n </nav>\n );\n}\n","export enum FeedbackType {\n Other,\n SuggestImprovement,\n ReportBug,\n RequestVideo,\n RaiseIssue,\n GivePraise,\n Footer,\n RequestLivestream\n}","import { BaseError } from 'libs/common/backbone/core/BaseError';\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Core } from 'libs/common/core';\n\nimport { NotFoundError } from 'libs/shared/errors/general/not-found/NotFoundError';\nimport { PrivateResourceError } from 'libs/shared/errors/general/private-resource/PrivateResourceError';\nimport { RegionLockedResourceError } from 'libs/shared/errors/general/region-locked-resource/RegionLockedResourceError';\nimport { UnspecifiedError } from 'libs/shared/errors/general/unspecified-error/UnspecifiedError';\nimport { VideoTypes } from 'libs/shared/interfaces';\n\nexport interface HttpErrorMap {\n notFound?: new () => BaseError;\n forbidden?: {\n rating?: new (description: string) => BaseError;\n yearLevel?: new (description: string) => BaseError;\n region?: new () => BaseError;\n privacy?: new (video?: VideoTypes) => BaseError;\n };\n badRequest?: new () => BaseError;\n internalServerError?: new () => BaseError;\n}\n\nexport type IgnoreHttpErrorMap = {\n [key in keyof HttpErrorMap]: boolean;\n};\n\nconst defaultErrors: HttpErrorMap = {\n notFound: NotFoundError,\n forbidden: {\n rating: PrivateResourceError,\n yearLevel: PrivateResourceError,\n region: RegionLockedResourceError,\n privacy: PrivateResourceError\n },\n badRequest: UnspecifiedError,\n internalServerError: UnspecifiedError\n};\n\nexport function handleHttpError(\n info: HttpStatus | Xhr,\n customErrorMap: HttpErrorMap = {},\n /**\n * Prevent certain errors in the errorMap from being thrown\n * so that you may implement your own handler\n */\n ignoreMap: IgnoreHttpErrorMap = {}\n): void {\n if (!info)\n return;\n\n let statusCode: HttpStatus;\n\n if (typeof(info) === 'number') {\n statusCode = info;\n } else {\n statusCode = info.status;\n }\n\n const errorMap = {\n ...defaultErrors,\n ...customErrorMap\n };\n\n if (!statusCode)\n return;\n\n if (!Core.ErrorHelper.isStatusCodeError(statusCode))\n return;\n\n if (statusCode === HttpStatus.InternalServer) {\n if (!ignoreMap.internalServerError)\n Core.ErrorHelper.throw(new UnspecifiedError());\n return;\n }\n\n if (statusCode === HttpStatus.NotFound) {\n if (!ignoreMap.notFound)\n Core.ErrorHelper.throw(new errorMap.notFound());\n return;\n }\n\n if (statusCode === HttpStatus.Forbidden) {\n /**\n * TODO: Work out how to go about handling all forbidden errors, such as region locking, year levels,\n * ratings, and privacy.\n */\n if (!ignoreMap.forbidden)\n Core.ErrorHelper.throw(new errorMap.forbidden.privacy());\n return;\n }\n\n if (!ignoreMap.badRequest)\n Core.ErrorHelper.throw(new errorMap.badRequest());\n}\n\nexport function handleXhrError(xhr: Xhr, customErrorMap?: HttpErrorMap): void {\n handleHttpError(xhr.status, customErrorMap);\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/react/index';\n\nimport { FeedbackFormRequest } from 'libs/shared/interfaces/requests/FeedbackFormRequest';\n\nexport const FeedbackRequests = {\n submitFeedback(requestData: FeedbackFormRequest, formValues: Record<string, string>): Flight.Request {\n return {\n url: '{gateway}/v1/feedback',\n key: 'submit:feedback',\n type: HttpVerbs.POST,\n data: {\n ...requestData,\n ...formValues\n }\n };\n }\n};","import { useEffect } from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { handleHttpError, HttpErrorMap, IgnoreHttpErrorMap } from 'libs/shared/errors/handlers/HttpErrorHandlers';\n\nfunction generateCacheKey(flightObjs: Array<Flight.Response<any>>): string {\n return flightObjs.map(obj => obj.statusCode).join(':');\n}\n\n// TODO: Change this to just `useHandleHttpError` and only accept a status code.\nexport function useHandleObjectError(\n _flightObjs: Flight.Response<any> | Array<Flight.Response<any>>,\n customErrors?: HttpErrorMap,\n ignoreErrors?: IgnoreHttpErrorMap\n): void {\n const flightObjs = Array.isArray(_flightObjs) ? _flightObjs : [_flightObjs];\n\n useEffect(() => {\n flightObjs.forEach(obj => {\n handleHttpError(obj.statusCode, customErrors, ignoreErrors);\n });\n }, [ generateCacheKey(flightObjs), customErrors, ignoreErrors ]);\n}","import React from 'react';\n\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { BreadcrumbService } from 'libs/shared/services/BreadcrumbService';\n\nexport function useBreadcrumbs(current: Breadcrumb): Breadcrumb[] {\n const [ match, useBuilder ] = React.useMemo(() => BreadcrumbService.getBuilder(), []);\n\n const breadcrumbs = useBuilder(match);\n\n if (!breadcrumbs || !current)\n return breadcrumbs;\n\n return [ ...breadcrumbs, { ...current, active: true }];\n}\n\n","import Dropzone from 'dropzone';\n\nimport { UploadItem } from 'libs/shared/apps/upload/services/UploadService';\nimport { FileExtensions } from 'libs/shared/apps/upload/utils/FileExtensionsHelper';\nimport { CountryCode } from 'libs/shared/enums/CountryCode';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { CurrentUser, Customer } from 'libs/shared/interfaces';\nimport { FeedbackUserDetails } from 'libs/shared/interfaces/requests/FeedbackFormRequest';\n\nconst COUNTRY_CODE_TAGS: { [key in CountryCode]: string } = {\n [CountryCode.AU]: 'au',\n [CountryCode.NZ]: 'nz',\n [CountryCode.UK]: 'uk',\n [CountryCode.US]: 'us',\n [CountryCode.CA]: 'ca'\n};\n\nexport const FeedbackFormHelper = {\n getUserInfo: (\n currentUser: CurrentUser,\n customer: Customer\n ): FeedbackUserDetails => {\n return {\n id: currentUser.id,\n username: currentUser.username,\n email: currentUser.email,\n userType: currentUser.role === UserRole.Admin ? 'Admin' : 'Staff',\n customerId: currentUser.customerId,\n cvcId: customer.crmId,\n customerName: customer.name,\n instanceRegion: currentUser.instanceRegion,\n contentRegion: currentUser.contentRegion,\n firstName: currentUser.givenName,\n lastName: currentUser.familyName\n };\n },\n\n mapCountryCodeToTag: (countryCode: CountryCode): string => {\n return COUNTRY_CODE_TAGS[countryCode.toLowerCase() as CountryCode];\n },\n\n getTags: (currentUser: CurrentUser, product: ProductId, hasStudentExperience: boolean, extraTags: string[]) => {\n const tags = [\n product,\n ...extraTags\n ];\n\n tags.push(hasStudentExperience ? 'student' : 'staff');\n \n if (currentUser.role === UserRole.Admin)\n tags.push('administrator');\n \n const countryCodeTag = FeedbackFormHelper.mapCountryCodeToTag(currentUser.countryCode);\n \n if (countryCodeTag)\n tags.push(countryCodeTag);\n\n return tags;\n },\n\n categorizeFiles(files: UploadItem[]) {\n return files.reduce((result, file) => {\n const fileInfo = file.get('fileInfo');\n if (Dropzone.isValidFile(file.get('file'), FileExtensions.VIDEO)) {\n result.videoUrls.push(fileInfo?.url);\n } else {\n result.imageUrls.push(fileInfo?.url);\n }\n return result;\n }, {\n imageUrls: [],\n videoUrls: []\n });\n }\n};","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Classification } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nconst namespace = 'subject.classificationHeaderDetails';\n\nconst Separator = ({ className }: { className: string }) =>\n <span className={className}>&bull;</span>;\n\ninterface ClassificationHeaderDetailsProps {\n classification: Classification;\n}\n\nexport function ClassificationHeaderDetails(props: ClassificationHeaderDetailsProps): React.ReactElement {\n const {\n dashboardVideoCount,\n childDashboardVideoCount,\n dashboardResourceCount,\n childDashboardResourceCount,\n childClassificationCount\n } = TopicsHelper.getCounts(props.classification);\n\n const videoCount = dashboardVideoCount + childDashboardVideoCount;\n const resourceCount = dashboardResourceCount + childDashboardResourceCount;\n\n return (\n <p className='mb-n1 font-size-normal fw-normal mt-1'>\n {!!childClassificationCount && (\n <Text\n namespace={namespace}\n phrase='topics'\n options={{ count: childClassificationCount.toLocaleString(), smartCount: childClassificationCount }}\n />\n )}\n\n {!!videoCount && (\n <>\n {childClassificationCount > 0 && <Separator className='mx-2' />}\n <Text\n namespace={namespace}\n phrase='videos'\n options={{ count: videoCount.toLocaleString(), smartCount: videoCount }}\n />\n </>\n )}\n {!!resourceCount && (\n <>\n <Separator className='mx-2' />\n <Text\n namespace={namespace}\n phrase='resources'\n options={{ count: resourceCount.toLocaleString(), smartCount: resourceCount }}\n />\n </>\n )}\n </p>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'subjects.curatedClassificationEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CuratedClassificationEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function CuratedClassificationEmptyState(props: CuratedClassificationEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('headingForNP')} />\n {!props.isReadonly ? (\n <EmptyState.Heading>\n <Text phrase='headingForNP' />\n </EmptyState.Heading>\n ) : (\n <>\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='headingForCurator' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={cvSvgLibrary.Plus}\n disabled={isArchived}\n />\n </Tooltip>\n </>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"container\":\"k1iOO\",\"mobile\":\"QwoBj\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { TableOfContentsList } from 'libs/shared/components/table-of-contents-list/TableOfContentsList';\nimport { CuratedWidget } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nimport styles from './table-of-contents.scss';\n\ninterface TableOfContentsContainerProps {\n widgets: CuratedWidget[];\n title: string;\n activeId: string;\n appLink?: Core.AppLink;\n clickable?: boolean;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n isSmallScreen?: boolean;\n}\ninterface TableOfContentsProps extends TableOfContentsContainerProps {\n getAppLink: (widget: CuratedWidget) => Core.AppLink\n}\n\nfunction TableOfContentsMobile(props: TableOfContentsProps) {\n const [ isExpanded, setIsExpanded ] = React.useState(false);\n\n function logUserAction() {\n const analyticsOptions = {\n actionType: !isExpanded ? UserAction.Open : UserAction.Hide,\n entity: EntityType.TableOfContents,\n location: LocationContext.Dashboard\n };\n\n AnalyticsHelper.logUserAction(props.analyticsData, analyticsOptions);\n }\n\n function onClickIcon() {\n setIsExpanded(!isExpanded);\n logUserAction();\n }\n\n return (\n <div className={`${styles.mobile} d-inline-flex gap-1`}>\n \n {isExpanded && (\n <div className='bg-white px-3 pt-3 pb-2 border border-dark rounded-1 ps-3'>\n <h2 className='h5'>{props.title}</h2>\n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n onItemClick={() => setIsExpanded(false)}\n />\n </div>\n )}\n <div className={styles.container}>\n <IconButton\n className='btn btn-outline-dark'\n svgName={cvSvgLibrary.TableOfContents}\n onClick={onClickIcon}\n />\n </div>\n </div>\n );\n}\n\nfunction TableOfContents(props: TableOfContentsProps): JSX.Element {\n return (\n <aside className='col-3 order-1'>\n <div className={`${styles.container} ps-3`}>\n <h2 className='h5'>{props.title}</h2>\n \n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n />\n </div>\n </aside>\n );\n}\n\nexport function TableOfContentsContainer(props: TableOfContentsContainerProps): JSX.Element {\n function getAppLink(widget: CuratedWidget): Core.AppLink {\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n \n const params: HashObject = currentAppLink.params\n ? { ...(currentAppLink.params as HashObject) }\n : {};\n\n params.tocId = widget.id;\n\n return {\n ...currentAppLink,\n params\n };\n }\n\n return (\n <>\n {!props.isSmallScreen\n ? <TableOfContents {...props} getAppLink={getAppLink} />\n : <TableOfContentsMobile {...props} getAppLink={getAppLink} />\n }\n </>\n );\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'subjects.teacherOnlyEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface TeacherOnlyEmptyStateProps {\n imageUrl: string;\n ctaAppLink?: () => Core.AppLink;\n}\n\nexport function TeacherOnlyEmptyState(props: TeacherOnlyEmptyStateProps): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('heading')} />\n <EmptyState.Heading>\n <Text phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text phrase='info' />\n </EmptyState.Info>\n\n <EmptyState.Cta\n text={getPhrase('cta')}\n appLink={props.ctaAppLink?.()}\n className='btn btn-dark'\n />\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Classification } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\n\nconst namespace = 'subjects.classificationComingSoon';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ComingSoonProps {\n data: Classification;\n onToggleFollow?: () => void;\n canFollowSubjects: boolean;\n imageUrl: string;\n showFollowButtonSpinner: boolean;\n showSignUp: boolean;\n signUpAppLink: Core.AppLink;\n}\n\nexport function ClassificationComingSoon(props: ComingSoonProps): JSX.Element {\n const isFollowing = !!props.data.followers?.data?.length;\n function onClick(): void {\n props.onToggleFollow?.();\n }\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState className='pt-0'>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('comingSoon')} />\n\n <EmptyState.Heading>\n <Text phrase='comingSoon' />\n </EmptyState.Heading>\n\n <EmptyState.Info>\n <Text phrase={props.showSignUp ? 'infoAnon' : 'info'} />\n </EmptyState.Info>\n\n {props.canFollowSubjects && (\n <ActionButton\n svgName={isFollowing ? cvSvgLibrary.BellFilled : cvSvgLibrary.Bell}\n onClick={onClick}\n showSpinner={props.showFollowButtonSpinner}\n className={`btn follow-btn me-2 ${isFollowing ? 'btn-outline-dark' : 'btn-dark'}`}\n >\n <Text phrase={isFollowing ? 'following' : 'follow'} />\n </ActionButton>\n )}\n\n {props.showSignUp && !props.canFollowSubjects && (\n <AppLink\n appLink={props.signUpAppLink}\n className='btn btn-dark d-none d-lg-inline-block'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.ClassificationComingSoon,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n }}\n analyticsData={{}}\n tag='button'\n >\n {getPhrase('signUp')}\n </AppLink>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","import * as React from 'react';\n\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Core } from 'libs/common/core';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AudienceItem } from 'libs/shared/apps/subjects/components/audience-item/AudienceItem';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\n\nconst namespace = 'subjects.audienceFilter';\n\ninterface AudienceFilterProps {\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n disabled?: boolean;\n appLink: Core.AppLink;\n disablePersist?: boolean;\n tooltip?: string;\n}\n\nexport function AudienceFilter(props: AudienceFilterProps): React.ReactElement {\n const { audiences, activeAudiences, appLink } = props;\n\n const isDisabled = props.disabled || !appLink;\n\n const [ , setActiveAudiences ] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n React.useEffect(() => {\n if (!props.disablePersist)\n setActiveAudiences(activeAudiences);\n }, [activeAudiences]);\n\n function onToggleAudience(audience: PresentationAudience, isSelected: boolean): void {\n if (isDisabled)\n return;\n\n const activeAudienceNames = isSelected\n ? [ ...(activeAudiences?.map(a => a.name) ?? []), audience.name ]\n : activeAudiences.map(a => a.name).filter(name => name !== audience.name);\n\n const getParams = () => {\n const otherParams = ObjectHelper.omit(appLink.params, ['a']);\n\n if (!activeAudienceNames.length)\n return otherParams;\n\n return Object.assign({}, otherParams, { a: activeAudienceNames });\n };\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params: getParams()\n }, { replace: true });\n }\n\n function onClickClearAudiences(): void {\n if (isDisabled)\n return;\n\n const params = ObjectHelper.omit(appLink.params, ['a']);\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params\n }, { replace: true });\n }\n\n if (!audiences || !audiences.length)\n return <></>;\n\n return (\n <Tooltip title={props.tooltip} spanHack>\n <div className='d-flex flex-wrap row-gap-2'>\n {audiences.map((a: PresentationAudience) => (\n <AudienceItem\n key={a.masterId}\n audience={a}\n highlight={!isDisabled && !!activeAudiences?.find(aa => aa.masterId === a.masterId)}\n setAudience={onToggleAudience}\n isDisabled={isDisabled}\n />\n ))}\n {(!isDisabled && !!activeAudiences && !!Object.keys(activeAudiences).length) && (\n <DivButton className='info-link d-inline-block ms-1' onClick={onClickClearAudiences}>\n <Text namespace={namespace} phrase='clear' />\n </DivButton>\n )}\n </div>\n </Tooltip>\n );\n}\n\nconst PARTIAL_AUDIENCES = PartialLoadingHelper.getPartialLoadingItems({ numItems: 6 });\n\nexport const PartialAudienceFilter = () => (\n <div className={'d-flex flex-wrap row-gap-2'}>\n {PARTIAL_AUDIENCES.map(({ width }, idx) => (\n <span\n key={idx}\n className='rounded-pill partial-loading-background me-1'\n dangerouslySetInnerHTML={{ __html: '&nbsp' }}\n style={{ width }}\n />\n ))}\n </div>\n);","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { AudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\ninterface ClassificationDashboardAudiencesProps {\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n appLink: Core.AppLink;\n disabled: boolean;\n disablePersist: boolean;\n tooltip: string;\n}\n\nexport function ClassificationDashboardAudiences(props: ClassificationDashboardAudiencesProps): JSX.Element {\n return (\n <AudienceFilter\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n disabled={props.disabled}\n appLink={props.appLink}\n disablePersist={props.disablePersist}\n tooltip={props.tooltip}\n />\n );\n}","// extracted by mini-css-extract-plugin\nexport default {\"curatedTopicTab\":\"CmVlO\",\"tabTransition\":\"rX31t\"};","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTab, PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\nimport { useProductTipsContext } from 'libs/shared/context/product-tips-context/ProductTipsContext';\nimport { Breakpoints, useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Classification, Presentation } from 'libs/shared/interfaces';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { useDirectoryTabProductTipSwitcher } from '../../../hooks/useDirectoryTabProductTipSwitcher';\n\nimport styles from './classification-tabs.scss';\n\nconst namespace = 'shared.classificationDashboard';\n\nexport type ClassificationTab = 'new-releases' | 'all-topics' | 'curated-topic' | 'curriculum';\n\nfunction getTabs(\n props: ClassificationTabsProps,\n breakpoints: Breakpoints,\n activeTab: ClassificationTab,\n isHighlighting: boolean\n): PillTab[] {\n const showText = breakpoints.lg || breakpoints.xl || breakpoints.xxl || breakpoints.xs;\n\n function getTopicTabClassName(): string {\n let className = isHighlighting ? styles.tabTransition : '';\n\n if (breakpoints.xs)\n return className + ' w-100';\n\n if (showText)\n return className = ` ${styles.curatedTopicTab}`;\n\n return className;\n }\n\n if (TopicsHelper.isTopLevelTopic(props.classification)) {\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'newReleases') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'new-releases',\n svgName: cvSvgLibrary.Sparkle,\n analyticsData: {\n id: 'new-releases',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'newReleases'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'allTopics') : '',\n appLink: props.appLinks?.classificationDirectory?.(props.classification),\n active: activeTab === 'all-topics',\n svgName: cvSvgLibrary.Grid,\n analyticsData: {\n id: 'all-topics',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'allTopics'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationDirectory?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n }\n\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'topic') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'curated-topic',\n svgName: cvSvgLibrary.Rectangles,\n analyticsData: {\n id: 'curated-topic',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'topic'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: getTopicTabClassName()\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'curriculum') : '',\n appLink: props.appLinks?.classificationCurriculum?.(props.classification),\n active: activeTab === 'curriculum',\n svgName: cvSvgLibrary.GraduationCap,\n analyticsData: {\n id: 'curriculum',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'curriculum'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationCurriculum?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n}\n\ninterface ClassificationTabsProps {\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n classification: (classification: Classification | null) => Core.AppLink;\n classificationDirectory: (classification: Classification) => Core.AppLink;\n classificationCurriculum: (classification: Classification) => Core.AppLink;\n };\n activeTab: ClassificationTab;\n}\n\nexport function ClassificationTabs(props: ClassificationTabsProps): JSX.Element {\n const breakpoints = useBreakpoints();\n const { tab, isHighlighting } = useDirectoryTabProductTipSwitcher(props.activeTab);\n\n const { setProductTipRef } = useProductTipsContext('topics-directory-tab');\n\n return (\n <PillTabSelector\n borderRadius='sm'\n containerRef={el => setProductTipRef(el)}\n className={breakpoints.xs ? 'w-100' : ''}\n listClassName='d-flex flex-nowrap'\n tabs={getTabs(props, breakpoints, tab, isHighlighting)}\n />\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Classification, CuratedDashboard, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ClassificationDashboardAudiences } from '../audiences/ClassificationDashboardAudiences';\nimport { ClassificationTab, ClassificationTabs } from '../classification-tabs/ClassificationTabs';\n\nfunction shouldHideAudiences(\n audiences: PresentationAudience[],\n activeAudiences: PresentationAudience[],\n activeTab: ClassificationTab,\n isEmpty: boolean,\n isComingSoon: boolean\n): boolean {\n if (isComingSoon)\n return true;\n\n if (isEmpty && !activeAudiences?.length)\n return true;\n\n if (!AudienceHelper.shouldShowAudiences(audiences))\n return true;\n\n if (activeTab === 'curriculum')\n return true;\n\n return false;\n}\n\ninterface ClassificationDashboardNavProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n audience: () => Core.AppLink;\n classification: (classification: Classification | null) => Core.AppLink;\n classificationDirectory: (classification: Classification) => Core.AppLink;\n classificationCurriculum: (classification: Classification) => Core.AppLink;\n };\n activeTab: ClassificationTab;\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n getBreadcrumbs: () => Breadcrumb[];\n\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isComingSoon: boolean;\n isEmpty: boolean;\n isViewingCurrentPresentation: boolean;\n disableAudiences: boolean;\n audienceTooltip: string;\n}\n\nexport function ClassificationDashboardNav(props: ClassificationDashboardNavProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const hideAudiences = shouldHideAudiences(\n props.audiences,\n props.activeAudiences,\n props.activeTab,\n props.isEmpty,\n props.isComingSoon\n );\n\n function canShowTabs(): boolean {\n if (!props.classification || !props.dashboard)\n return false;\n\n if (CuratedDashboardHelper.isSystemGeneratedDashboard(props.dashboard.widgets))\n return false;\n\n /**\n * For our top-level topics, we can show the topic tab if the topic has a directory dashboard.\n */\n if (TopicsHelper.isTopLevelTopic(props.classification))\n return props.hasTopicDirectoryDashboard;\n\n /**\n * For our curated topics, we can show the curriculum tab if the topic has one, which it should\n */\n if (props.classification.externalMetadata?.isCurated && props.hasTopicCurriculumDashboard)\n return true;\n\n return false;\n }\n\n function getContainerClass(): string {\n let className = 'd-flex flex-column py-3 mb-3';\n\n if (!props.isComingSoon)\n className += ' border-bottom';\n\n if ((canShowTabs() || hideAudiences) && !breakpoints.xs)\n return className;\n\n return className + ' row-gap-3';\n }\n\n function getTopRowClass(): string {\n if (hideAudiences) {\n if (breakpoints.xs)\n return 'd-flex flex-column justify-content-between row-gap-3';\n\n return 'd-flex align-items-center justify-content-between';\n }\n\n let className = '';\n\n className += 'd-flex align-items-center justify-content-between mb-1';\n\n if (breakpoints.xs)\n className += ' row-gap-3 mb-0';\n\n return className;\n }\n\n function getBottomRowClass(): string {\n let className = 'd-flex align-items-end justify-content-between';\n\n if (breakpoints.xs)\n className += ' row-gap-3 flex-wrap';\n\n return className;\n }\n\n return (\n <div className={getContainerClass()}>\n <div className={getTopRowClass()}>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n\n {canShowTabs() && hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n\n <div className={getBottomRowClass()}>\n {!hideAudiences && (\n <ClassificationDashboardAudiences\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n appLink={props.appLinks.audience?.()}\n disabled={props.disableAudiences}\n tooltip={props.audienceTooltip}\n disablePersist={!props.isViewingCurrentPresentation}\n />\n )}\n\n {canShowTabs() && !hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n </div>\n );\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsOptions, HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { ClassificationHeaderDetails } from 'libs/shared/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails';\nimport { CuratedClassificationEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState';\nimport { TableOfContentsContainer } from 'libs/shared/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents';\nimport { TeacherOnlyEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState';\nimport { useGetTopicsWidgets } from 'libs/shared/apps/subjects/hooks/useGetTopicsWidgets';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { VideoList } from 'libs/shared/components/video-list/VideoList';\nimport { WidgetHeader } from 'libs/shared/components/widgets/curated-widgets/components/header/WidgetHeader';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllClassificationWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { LocalPermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { useTableOfContentsActiveHeading } from 'libs/shared/hooks/useTableOfContentsActiveHeading';\nimport { useTableOfContentsScroll } from 'libs/shared/hooks/useTableOfContentsScroll';\nimport { CalendarEvent, CalendarEventContentType, Classification, CuratedDashboard, CuratedWidget, CuratedWidgetQueryParams, CurriculumData, DashboardStatus, DashboardTargetType, InteractiveMetadata, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ClassificationComingSoon } from './classification-coming-soon/ClassificationComingSoon';\nimport { ClassificationDashboardNav } from './classification-dashboard-nav/ClassificationDashboardNav';\nimport { ClassificationTab } from './classification-tabs/ClassificationTabs';\n\nconst namespace = 'shared.classificationDashboard';\n\nfunction isHeadingWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.Blurb && widget.templateId === WidgetTemplate.Heading;\n}\n\nfunction isTopicWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.CuratedClassifications || widget.widgetId === WidgetTypeId.Classifications;\n}\n\nexport interface ClassificationDashboardProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n resourceThumbnailFallbackImageUrl: string;\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isTertiaryCustomerWithoutExchange: boolean;\n tab: ClassificationTab;\n specialEvent?: CalendarEvent;\n curriculums: CurriculumData;\n\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n getBannerActions?: () => ActionOptions[];\n getBreadcrumbs?: () => Breadcrumb[];\n onToggleFollow?: (classification: Classification, locationContext: LocationContext) => void;\n canFollowSubjects: boolean;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n\n appLinks?: AllClassificationWidgetTemplates['appLinks'] & {\n signUp: () => Core.AppLink;\n widgetWizard: () => Core.AppLink;\n previewQuestions: (interactive: InteractiveMetadata) => Core.AppLink\n classificationCurriculum: (classification: Classification) => Core.AppLink;\n audience: () => Core.AppLink;\n };\n\n imageCdnUrl: string\n emptyImageUrl: string;\n comingSoonImageUrl?: string;\n\n analyticsOptions?: AnalyticsOptions;\n analyticsData?: HashObject;\n\n scrollToWidgetId?: string;\n tableOfContentsId?: string;\n\n // Means the dashboard contains no linked or working filters\n isReadonly?: boolean;\n\n // Means the dashboard is being previewed by ClickView staff either in product or in curator\n isPreviewing?: boolean;\n\n // Means the parent topic for the dashboard has a status of \"Coming Soon\"\n isComingSoon?: boolean;\n\n showFollowButtonSpinner?: boolean;\n \n isViewCurrentPresentation?: boolean;\n\n // By default widgets will always be lazyloaded. We override this behaviour only in extenuating \n // circumstances, such as dynamic rendering for SEO.\n lazyLoad?: boolean;\n\n moviesAndTv?: boolean;\n\n isTeacherOnly?: boolean;\n \n contentType?: CalendarEventContentType;\n\n isBot?: boolean;\n\n settings?: AllClassificationWidgetTemplates['settings'];\n\n commonVideoProps: CommonVideoProps;\n}\n\nClassificationDashboard.defaultProps = {\n appLinks: {}\n};\n\nexport function ClassificationDashboard(props: ClassificationDashboardProps): JSX.Element {\n const { widgets, videoList, videoListWidgetId } = useGetTopicsWidgets(props.dashboard, props.activeAudiences);\n\n const isSmallScreen = useMediaQuery(MediaQueryStrings.LGDown);\n const headingRef = React.useRef<Set<Element>>(new Set());\n\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n\n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n const [ controlledId, setControlledId ] = React.useState(props.tableOfContentsId);\n\n const [ tableOfContentActiveId, setTableOfContentActiveId ] = React.useState<string>('');\n\n const headingElements = Array.from(headingRef.current);\n useTableOfContentsScroll(headingElements, controlledId);\n useTableOfContentsActiveHeading({\n setActiveId: setTableOfContentActiveId,\n headingElements,\n controlledId,\n setControlledId\n });\n\n function shouldShowEmptyState(): boolean {\n if (props.isComingSoon)\n return false;\n\n if (props.isTeacherOnly)\n return false;\n\n if (!props.dashboard)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Archived && !props.isReadonly)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Draft && !props.isPreviewing)\n return true;\n\n if (!widgets?.length)\n return true;\n\n if (videoList && videoList.length)\n return false;\n\n return Object.values(emptyWidgets).every(state => !!state);\n }\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard),\n props.activeAudiences?.map(a => a.masterId),\n props.curriculums.preferredCurriculum?.id\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = shouldShowEmptyState();\n\n React.useEffect(() => {\n /**\n * When we add the first widget of the dashboard, the showEmptyState is `true`, the WidgetContainer is not going to be rendered to lazyload the `content`\n * so we set the emptyWidget to initial make sure the widget container is rendered to lazyload `widget.content`\n * and let the WidgetContainer to re-set the empty state based on the actual `widget.content` from backend\n */\n if (showEmptyState) {\n setEmptyWidgets(initialEmptyWidgets);\n }\n }, [widgets?.length]);\n\n const onSetIsEmpty = React.useCallback((widgetId: string, isEmpty: boolean) => {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n // The logic beneath this if-block doesn't apply to classification directories. This is because\n // classification directories don't support audience filtering, so widgets should never be empty,\n // meaning headings should never be hidden.\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.ClassificationDirectory)) {\n setEmptyWidgets(newEmptyState);\n return;\n }\n\n let index = 0;\n\n /**\n * Every time a widget is identified as empty, we check each heading blurb widget\n * to see if it should be hidden. This will be the case when all widgets beneath a heading\n * (up until the next heading) are empty.\n */\n while (index < widgets.length) {\n const currentWidget = widgets[index];\n\n if (!isHeadingWidget(currentWidget)) {\n index++;\n continue;\n }\n\n let isHeadingEmpty = true;\n let subWidgetIndex = index + 1;\n\n while (isHeadingEmpty && subWidgetIndex < widgets.length) {\n const headingSubWidget = widgets[subWidgetIndex];\n\n if (isHeadingWidget(headingSubWidget))\n break;\n\n if (!newEmptyState[headingSubWidget.id] && !isTopicWidget(headingSubWidget))\n isHeadingEmpty = false;\n\n subWidgetIndex++;\n }\n\n index = subWidgetIndex;\n\n newEmptyState[currentWidget.id] = isHeadingEmpty;\n }\n\n setEmptyWidgets(newEmptyState);\n }, [ emptyWidgets, widgets ]);\n\n function hideWidget(widget: CuratedWidget): boolean {\n return isHeadingWidget(widget) && emptyWidgets[widget.id];\n }\n\n function useLargeDashboardSpacing(): boolean {\n const target = CuratedDashboardHelper.getDashboardTargetType(props.dashboard);\n\n if (props.moviesAndTv || target === DashboardTargetType.ClassificationCurriculum)\n return false;\n\n return true;\n }\n\n function getWidgetHeading(widget: CuratedWidget, index: number): string {\n if (widget.widgetId === WidgetTypeId.ClassificationDashboardExternalMedia) {\n const previousWidget = widgets[index - 1];\n\n if (emptyWidgets[previousWidget.id])\n return widget.name.replace('Other videos', 'Videos');\n\n return widget.name;\n }\n\n return widget.name;\n }\n\n const widgetsInTableOfContents = widgets.filter(w => {\n return !hideWidget(w) && !!w.metadata?.showInTableOfContents;\n });\n\n const isTopicOnlyDashboard = widgets.every(isTopicWidget);\n\n const shouldShowTableOfContents = widgetsInTableOfContents.length >= 2;\n const shouldShowSideTableOfContents = shouldShowTableOfContents && !isSmallScreen;\n\n const shouldShowTopicCounts = (\n props.settings?.hasTopicDirectories &&\n TopicsHelper.isTopLevelTopic(props.classification) &&\n !props.isTertiaryCustomerWithoutExchange\n );\n\n /**\n * We don't put the .topic-dashboard class when we're in a movies and tv classification\n * because we don't want the extra padding between widgets.\n */\n return (\n <div className={`bg-white px-4 ${useLargeDashboardSpacing() ? 'dashboard-spacing-lg' : ''}`}>\n <BannerHeader\n heading={props.classification.name}\n banner={props.classification.banner}\n imageCdnUrl={props.imageCdnUrl}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n specialEvent={props.specialEvent}\n calendarTheme={{\n background: 'bg-light-blue',\n border: 'border-light-blue'\n }}\n showComingSoon={props.isComingSoon}\n detailsComponent={shouldShowTopicCounts\n ? () => <ClassificationHeaderDetails classification={props.classification} />\n : null\n }\n />\n\n <ClassificationDashboardNav\n dashboard={props.dashboard}\n classification={props.classification}\n presentation={props.presentation}\n appLinks={props.appLinks}\n activeTab={props.tab}\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n getBreadcrumbs={props.getBreadcrumbs}\n hasTopicDirectoryDashboard={props.hasTopicDirectoryDashboard}\n hasTopicCurriculumDashboard={props.hasTopicCurriculumDashboard}\n isComingSoon={props.isComingSoon}\n isEmpty={showEmptyState}\n isViewingCurrentPresentation={props.isViewCurrentPresentation}\n disableAudiences={isTopicOnlyDashboard || props.isReadonly}\n audienceTooltip={isTopicOnlyDashboard ? LanguageService.getPhrase(namespace, 'audienceTooltip') : ''}\n />\n\n {props.isComingSoon && (\n <ClassificationComingSoon\n imageUrl={props.comingSoonImageUrl}\n data={props.classification}\n canFollowSubjects={props.canFollowSubjects}\n showFollowButtonSpinner={props.showFollowButtonSpinner}\n onToggleFollow={() => props.onToggleFollow(props.classification, LocationContext.ClassificationComingSoon)}\n showSignUp={!props.hasLocalPermissions(LocalPermissionName.FollowComingSoonTopics)}\n signUpAppLink={props.appLinks.signUp?.()}\n />\n )}\n\n {!props.isComingSoon && (\n <div className={`${shouldShowSideTableOfContents ? 'row no-wrap' : ''}`}>\n {shouldShowTableOfContents && (\n <TableOfContentsContainer\n widgets={widgetsInTableOfContents}\n title={props.classification.name}\n activeId={tableOfContentActiveId}\n clickable={!props.isReadonly}\n analyticsData={props.analyticsData}\n setControlledId={setControlledId}\n isSmallScreen={isSmallScreen}\n />\n )}\n\n <div className={shouldShowSideTableOfContents ? 'col-9 order-0' : ''}>\n {widgets.map((widget, idx) => {\n if (hideWidget(widget))\n return <React.Fragment key={widget.id}></React.Fragment>;\n\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Classification}\n headingElementRef={headingRef}\n key={widget.id}\n id={widget.id}\n name={getWidgetHeading(widget, idx)}\n description={widget.description}\n classification={props.classification}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n audiences={props.audiences}\n getContentRequest={getWidgetContentRequest}\n setIsEmpty={onSetIsEmpty}\n appLinks={props.appLinks}\n presentation={props.presentation}\n analyticsData={props.analyticsData}\n isScrollToTargetWidget={props.scrollToWidgetId === widget.id}\n imageCdnUrl={props.imageCdnUrl}\n onSubmitFeedback={props.onSubmitFeedback}\n metadata={widget.metadata}\n isBot={props.isBot}\n hasTableOfContents={shouldShowSideTableOfContents}\n lazyLoad={props.lazyLoad}\n dashboardTarget={CuratedDashboardHelper.getDashboardTargetType(props.dashboard)}\n widgetIndex={idx}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n contentType={props.contentType}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n onToggleFollowClassification={props.onToggleFollow}\n settings={props.settings}\n isEditing={props.isReadonly}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n commonVideoProps={props.commonVideoProps}\n curriculums={props.curriculums}\n\n // TODO: Do we actually need this shit if it wasn't even being passed in?\n limitTotalItems={false}\n seeMoreLink={null}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n </div>\n\n {!!videoList?.length && (\n <>\n <WidgetHeader name={LanguageService.getPhrase(namespace, 'videos')} />\n <VideoList\n videos={videoList}\n getVideoAppLink={(video, opts) => props.appLinks.videoType(\n video,\n { ...opts, contextId: videoListWidgetId, includeContext: opts.includeContext }\n )}\n hasPermissions={props.hasPermissions}\n presentationAudiences={props.audiences}\n getPreviewQuestionsAppLink={props.appLinks.previewQuestions}\n commonVideoProps={props.commonVideoProps}\n />\n </>\n )}\n </div>\n )}\n\n {showEmptyState && (\n <CuratedClassificationEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.appLinks.widgetWizard}\n />\n )}\n\n {props.isTeacherOnly && (\n <TeacherOnlyEmptyState\n imageUrl={props.emptyImageUrl}\n ctaAppLink={() => props.appLinks.allTopics(props.classification.presentationId)}\n />\n )}\n </div>\n );\n}","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { CuratedDashboard, CuratedMediaWidget, CuratedWidget, PresentationAudience, Video } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nexport interface Response {\n widgets: CuratedWidget[];\n\n videoList?: Video[];\n videoListWidgetId?: string;\n}\n\n/**\n * This hook helps us with custom logic for to display system generated dashboards in a slightly\n * different way.\n */\nexport function useGetTopicsWidgets(dashboard: CuratedDashboard, activeAudiences: PresentationAudience[]): Response {\n const {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget\n } = React.useMemo(() => {\n if (!dashboard) {\n return {\n isSystemGeneratedDashboard: false,\n systemGeneratedVideoWidget: null\n };\n }\n\n const isSystemGeneratedDashboard = CuratedDashboardHelper.isSystemGeneratedDashboard(dashboard.widgets);\n\n return {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget: dashboard.widgets.find(widget => {\n return (\n widget.widgetId === WidgetTypeId.ClassificationPinnedVideos &&\n widget.templateId !== WidgetTemplate.ThumbnailVerticalList\n );\n })\n };\n }, [dashboard?.id]);\n\n const systemGeneratedVideoContent = Flight.useBasicFetch<CuratedMediaWidget<Video[]>>(\n !!systemGeneratedVideoWidget &&\n DashboardRequests.dashboardWidgetContent(\n systemGeneratedVideoWidget?.id,\n CuratedDashboardHelper.getWidgetParams(\n systemGeneratedVideoWidget.widgetId,\n systemGeneratedVideoWidget.templateId,\n CuratedDashboardHelper.getDashboardTargetType(dashboard),\n activeAudiences?.map(a => a.masterId)\n ),\n systemGeneratedVideoWidget?.templateId\n )\n );\n\n // Non system generated dashboards are returned as per usual\n if (!isSystemGeneratedDashboard)\n return { widgets: ArrayHelper.sortBy(dashboard?.widgets, 'index') };\n\n // System generated dashboard have the video widget removed and returned as a separate video list\n return {\n widgets: dashboard?.widgets?.filter(widget => {\n if (widget.widgetId !== WidgetTypeId.ClassificationPinnedVideos)\n return true;\n\n if (widget.templateId === WidgetTemplate.ThumbnailVerticalList)\n return true;\n\n return false;\n }) ?? [],\n videoList: systemGeneratedVideoContent.data?.content ?? [],\n videoListWidgetId: systemGeneratedVideoWidget?.id\n };\n}","import React from 'react';\n\nimport { PartialAudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { PartialBreadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\n\nexport function PartialClassificationDashboard(): JSX.Element {\n return (\n <div className='bg-white px-4'>\n <PartialBannerHeader />\n\n <div className='d-flex flex-column row-gap-3 py-3 mb-3 border-bottom'>\n <PartialBreadcrumbs />\n <PartialAudienceFilter />\n </div>\n </div>\n );\n}","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nconst endpoints = {\n follow: () => `{gateway}/v1/users/me/classifications/following`,\n unfollow: (ids: string[]) => UrlHelper.urlBuilder('{gateway}/v1/users/me/classifications/following', { id: ids })\n};\n\nexport const FollowRequests = {\n /**\n * @param data - array of object ids the user is going to follow\n */\n follow(\n ids: string[],\n userId: string,\n success?: (data: string[]) => void,\n error?: () => void\n ): Flight.Request {\n return {\n url: endpoints.follow(),\n key: `follow:${ids.join(',')}`,\n type: HttpVerbs.POST,\n data: ids,\n formatData: () => {\n return ids.map(id => ({\n id,\n followers: {\n data: [userId]\n }\n }));\n },\n success,\n error,\n invalidationKeys: [ ...ids.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications' ]\n };\n },\n\n unfollow(ids: string[], userId: string, success?: () => void, error?: () => void): Flight.Request {\n return {\n url: endpoints.unfollow(ids),\n key: `unfollow:${ids.join(',')}`,\n type: HttpVerbs.DELETE,\n formatData: () => {\n return ids.map(id => ({\n id,\n followers: {\n data: []\n }\n }));\n },\n success,\n error,\n invalidationKeys: [ ...ids.map(id => `classification:${id}`), 'my:subject:preferences', 'classifications' ]\n };\n }\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { ErrorCta, ErrorPageError } from 'libs/shared/errors/primitives/ErrorPageError';\n\nimport { Actions } from 'shared/constants/LiteActions';\nimport { AppChannels } from 'shared/constants/LiteRadioChannels';\n\nconst namespace = 'subjects.topicNotFoundError';\n\nexport class TopicNotFoundError extends ErrorPageError {\n constructor() {\n super('Topic doesn\\'t exist');\n }\n\n // @ts-ignore\n public get name(): string {\n return 'TopicNotFoundError';\n }\n\n // @ts-ignore\n public get heading(): string {\n return LanguageService.getPhrase(namespace, 'heading');\n }\n\n // @ts-ignore\n public get description(): string {\n return LanguageService.getPhrase(namespace, 'description');\n }\n\n // @ts-ignore\n public get cta(): ErrorCta {\n return {\n text: LanguageService.getPhrase(namespace, 'cta'),\n appLink: {\n application: AppChannels.SUBJECT,\n action: Actions.Subjects.PRESENTATION_TOPICS\n }\n };\n }\n}","// extracted by mini-css-extract-plugin\nexport default {\"followButton\":\"HlRXj\"};","import React from 'react';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, ToggleDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { CalendarRequests } from 'libs/shared/apps/calendar/flight-request/CalendarRequests';\nimport { LibraryHelper } from 'libs/shared/apps/libraries/utils/LibraryHelper';\nimport { ClassificationDashboard } from 'libs/shared/apps/subjects/components/classification-dashboard/ClassificationDashboard';\nimport { PartialClassificationDashboard } from 'libs/shared/apps/subjects/components/classification-dashboard/partial-loading/PartialClassificationDashboard';\nimport { PreviewBanner } from 'libs/shared/apps/subjects/components/preview-banner/PreviewBanner';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { VideoActionsContext } from 'libs/shared/context/VideoActionsContext';\nimport { ClassificationStatus } from 'libs/shared/enums/ClassificationStatus';\nimport { FeedbackType } from 'libs/shared/enums/FeedbackType';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { CustomerRequests } from 'libs/shared/flight-requests/CustomerRequests';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { FeedbackRequests } from 'libs/shared/flight-requests/FeedbackRequests';\nimport { FollowRequests } from 'libs/shared/flight-requests/FollowRequests';\nimport { LibraryRequests } from 'libs/shared/flight-requests/LibraryRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useBreadcrumbs } from 'libs/shared/hooks/useBreadcrumbs';\nimport { useCurationStudio } from 'libs/shared/hooks/useCurationStudio';\nimport { useHandleObjectError } from 'libs/shared/hooks/UseHandleObjectError';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\nimport { CalendarEvent, Classification, Config, CuratedWidgetQueryParams, CurrentUser, Customer, DashboardTargetType, Library, Presentation, PresentationAudience, RegionAlternative } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { FeedbackFormHelper } from 'libs/shared/utils/FeedbackFormHelper';\nimport { PageMetadataHelper } from 'libs/shared/utils/PageMetadataHelper';\nimport { cvSvgLibrary } from 'libs/shared/utils/SvgHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { useVideoActions, VideoActionsLocation } from 'shared/hooks/use-video-actions/useVideoActions';\nimport { useCommonVideoProps } from 'shared/hooks/useCommonVideoProps';\nimport { useCurriculums } from 'shared/hooks/useCurriculums';\nimport { useDeepLinks } from 'shared/hooks/useDeepLinks';\nimport { usePresentation } from 'shared/hooks/usePresentation';\nimport { ClassificationAppLinkHelper } from 'shared/utils/ClassificationAppLinkHelper';\nimport { InteractiveHelpers } from 'shared/utils/InteractiveHelper';\nimport { SeoHelper } from 'shared/utils/SeoHelper';\n\nimport { useIsTertiary } from 'apps/onboarding/hooks/useIsTertiary';\nimport { SignUpHelper } from 'apps/sign-up/utils/SignUpHelper';\nimport { TopicNotFoundError } from 'apps/subjects/errors/TopicNotFoundError';\nimport { useFetchClassificationDashboard } from 'apps/subjects/hooks/useFetchClassificationDashboard';\n\nimport { ClassificationViewQueryParams, getClassificationAppLinks } from './ClassificationViewUtils';\n\nimport styles from './curated-classification-view.scss';\n\ninterface CuratedClassificationViewProps {\n id: string;\n queryParams?: ClassificationViewQueryParams;\n targetType: DashboardTargetType;\n}\n\nCuratedClassificationView.defaultProps = {\n queryParams: {}\n};\n\nconst namespace = 'subjects.classification';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function CuratedClassificationView(props: CuratedClassificationViewProps): React.ReactElement {\n const [ showFollowButtonSpinner, setShowFollowButtonSpinner ] = React.useState<boolean>(false);\n\n const alerts = useAlerts();\n const fetchAsync = Flight.useGetFetchAsync();\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n const settings = useSettings(null);\n\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const { openInCurationStudioLabel, isUserCurator, getOpenInCurationStudioLink } = useCurationStudio();\n const curriculums = useCurriculums();\n\n const customer = Flight.useBasicFetch<Customer>(\n hasPermissions(PermissionName.CanSubmitFeedback) &&\n currentUser.data?.isAuthenticated &&\n CustomerRequests.customer(currentUser.data.customerId)\n );\n\n const classification = Flight.useBasicFetch<Classification>(\n ClassificationRequests.classification(props.id, currentUser.data?.id)\n );\n\n const presentation = Flight.useBasicFetch<Presentation>(\n classification.data &&\n ClassificationRequests.presentationById(classification.data.presentationId)\n );\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n classification.data &&\n AudienceRequests.audiencesByPresentationId(classification.data.presentationId)\n );\n\n const specialEvent = Flight.useBasicFetch<CalendarEvent>(\n classification.data &&\n CalendarRequests.nextTopicSpecialEvent(props.id, classification.data.presentationId)\n );\n\n const libraries = Flight.useBasicFetch<Library[]>(\n currentUser.data?.isAuthenticated &&\n LibraryRequests.libraries()\n );\n\n const {\n activePresentation,\n availablePresentations,\n canAccessPresentation\n } = usePresentation();\n\n const path = Flight.useBasicFetch<Classification[]>(ClassificationRequests.path(props.id));\n\n const {\n dashboard,\n hasTopicDirectoryDashboard,\n hasTopicCurriculumDashboard,\n isPreviewing,\n isTeacherOnly\n } = useFetchClassificationDashboard(props.id, props.queryParams, props.targetType);\n\n const isTertiary = useIsTertiary();\n const products = useProducts();\n\n const regionAlternatives = Flight.useBasicFetch<RegionAlternative[]>(\n ClassificationRequests.regionAlternatives(props.id)\n );\n\n const preferredRegionAlternative = SeoHelper.getPreferredRegionAlternative(\n regionAlternatives.data,\n currentUser.data?.contentRegion\n );\n useSetPageMetadata(PageMetadataHelper.getClassificationMetadata({\n content: { classification: classification.data, dashboard: dashboard.data },\n\n phraseContext: {\n phraseHandler: getPhrase,\n titlePhrase: 'pageTitle',\n descriptionPhrase: 'pageDescription'\n },\n canonicalLink: SeoHelper.getCanonicalLink({\n stripPresentationSlug: true,\n customAppLink: ClassificationAppLinkHelper.getAppLink({\n ...classification.data,\n name: preferredRegionAlternative?.name || classification.data?.name\n }, props.queryParams),\n hrefTransformer: SeoHelper.createRegionHrefTransformer(\n regionAlternatives.data,\n currentUser.data?.contentRegion\n )\n }),\n allowIndexing: SeoHelper.allowIndexing(),\n hrefLang: SeoHelper.getContentHrefLang(regionAlternatives.data, () => (\n ClassificationAppLinkHelper.getAppLink(classification.data)\n ))\n }));\n\n useHandleObjectError(classification, {\n notFound: TopicNotFoundError\n });\n useDeepLinks({ id: props.id, app: 'topics' });\n\n const isViewCurrentPresentation = activePresentation?.id === presentation.data?.id;\n \n const isSmallScreen = useMediaQuery(MediaQueryStrings.MDDown);\n const isMobile = useMediaQuery(MediaQueryStrings.SMDown);\n\n const { commonVideoProps } = useCommonVideoProps({\n locationContext: LocationContext.VideoThumbnail,\n mtv: props.queryParams.mtv\n });\n const videoActions = useVideoActions({ location: VideoActionsLocation.VideoItem });\n\n const canFollowSubjects = hasPermissions(PermissionName.FollowSubjects);\n const isComingSoon = (\n classification.data?.status === ClassificationStatus.ComingSoon &&\n !isPreviewing\n );\n\n /**\n * We use the current active audiences to re-fetch content for that specific audience set.\n */\n const activeAudiences = AudienceHelper.getActiveAudiencesFromParams(audiences.data, props.queryParams);\n const activeAudienceIds = activeAudiences?.map(a => a.masterId) ?? [];\n\n const targetType = CuratedDashboardHelper.getDashboardTargetType(dashboard.data);\n\n /**\n * Following\n */\n function onToggleFollow(followedClassification: Classification, location: LocationContext) {\n if (!canFollowSubjects || !classification)\n return;\n\n const isTogglingCurrentTopic = followedClassification.id.toString() === classification.data?.id?.toString();\n\n if (isTogglingCurrentTopic)\n setShowFollowButtonSpinner(true);\n\n const isFollowing = TopicsHelper.isFollowing(followedClassification);\n\n const request = isFollowing\n ? FollowRequests.unfollow\n : FollowRequests.follow;\n\n fetchAsync(request([followedClassification.id], currentUser.data?.id))\n .then(() => {\n AnalyticsHelper.logUserAction(analyticsData, {\n location,\n actionType: UserAction.Follow,\n workflowPhase: WorkflowPhase.Complete,\n descriptor: isFollowing ? ToggleDescriptor.Off : ToggleDescriptor.On,\n entity: EntityType.Classification\n });\n\n if (!isTogglingCurrentTopic) {\n alerts.success(getPhrase(isFollowing ? 'unfollowed' : 'followed', { name: followedClassification.name }));\n }\n })\n .finally(() => {\n if (isTogglingCurrentTopic)\n setShowFollowButtonSpinner(false);\n });\n }\n\n async function onSubmitFeedback(feedback: DashboardFeedbackData): Promise<void> {\n const promise = await fetchAsync<void>(FeedbackRequests.submitFeedback({\n type: FeedbackType.Footer,\n user: FeedbackFormHelper.getUserInfo(currentUser.data, customer.data),\n tags: FeedbackFormHelper.getTags(\n currentUser.data,\n ProductId.Primary,\n hasPermissions(PermissionName.StudentExperience),\n [ 'topics', 'in product feedback' ]\n )\n }, {\n reaction: feedback.type,\n feedback: feedback.content,\n location: 'Topic Footer',\n presentationName: presentation.data.description,\n presentationId: presentation.data.id,\n dashboardName: dashboard.data.name,\n dashboardId: dashboard.data.id,\n classificationName: classification.data.name,\n classificationId: classification.data.id,\n currentPageUrl: LocationUtils.GetCurrentUrl()\n }));\n\n AnalyticsHelper.logUserAction({\n feedbackType: feedback.type,\n content: feedback.content,\n presentationId: presentation.data.id,\n classificationId: classification.data.id,\n dashboardId: dashboard.data.id\n }, {\n actionType: UserAction.Submit,\n location: LocationContext.ClassificationFooter,\n entity: EntityType.Feedback,\n workflowPhase: WorkflowPhase.Complete\n });\n\n return promise;\n }\n\n function getBannerActions(): ActionOptions[] {\n const isFollowing = !!classification.data?.followers?.data?.length;\n\n if (!canFollowSubjects)\n return [];\n\n const actions: ActionOptions[] = [{\n label: isMobile ? '' : getPhrase(isFollowing ? 'following' : 'follow'),\n onClick: () => onToggleFollow(classification.data, LocationContext.Banner),\n svgName: isFollowing ? cvSvgLibrary.BellFilled : cvSvgLibrary.Bell,\n className: `btn follow-btn me-2 ${isFollowing ? 'btn-outline-dark' : 'btn-dark'} ${styles.followButton}`,\n button: true,\n tooltip: (isFollowing || isSmallScreen) ? undefined : getPhrase('followBtnTooltip'),\n showSpinner: showFollowButtonSpinner\n }];\n\n if (isUserCurator)\n actions.push({\n label: openInCurationStudioLabel,\n href: getOpenInCurationStudioLink(MasterType.Subject, classification.data?.id, presentation.data?.id),\n openInNewTab: true\n });\n \n return actions;\n }\n\n const appLinks = getClassificationAppLinks(\n classification.data,\n targetType,\n props.queryParams,\n currentUser.data\n );\n\n const breadcrumbs = useBreadcrumbs({ name: classification.data?.name });\n function getBreadcrumbs(): () => Breadcrumb[] {\n if (!canAccessPresentation(presentation.data?.id))\n return;\n\n return () => breadcrumbs;\n }\n \n /**\n * Additional topics data to be mixed in with lower-level component analytics collection\n */\n const analyticsData = {\n presentationId: presentation.data?.id,\n presentationName: presentation.data?.name,\n currentClassificationId: classification.data?.id,\n currentClassificationName: classification.data?.name,\n followingCurrentClassification: !!classification.data?.followers?.data?.length,\n activeAudienceNames: activeAudiences?.length ? activeAudiences.map(a => a.name) : null,\n activeAudienceIds: activeAudienceIds.length ? activeAudienceIds : null\n };\n\n const dataLoaded = !!config.data\n && dashboard.hasCompleted\n && !!classification.data\n && !!presentation.data\n && !!path.data\n && !!availablePresentations\n && !!audiences.data\n && specialEvent.hasCompleted;\n\n if (!dataLoaded)\n return <PartialClassificationDashboard />;\n\n return (\n <VideoActionsContext.Provider value={videoActions}>\n <div className='position-relative'>\n {!!(isPreviewing && dashboard.data) && <PreviewBanner status={dashboard.data.status} type='topic' />}\n <ClassificationDashboard\n dashboard={dashboard.data}\n classification={classification.data}\n getWidgetContentRequest={(\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => {\n const { hasTwig, hasTigtag } = LibraryHelper.hasTwigOrTigtag(libraries.data, currentUser.data);\n \n return DashboardRequests.dashboardWidgetContent(\n id,\n params,\n widgetTemplate,\n presentation.data,\n { hideTigTag: !hasTigtag, hideTwig: !hasTwig }\n );\n }}\n getBreadcrumbs={getBreadcrumbs()}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n presentation={presentation.data}\n curriculums={curriculums}\n onToggleFollow={onToggleFollow}\n getBannerActions={getBannerActions}\n audiences={props.queryParams.mtv ? null : audiences.data}\n activeAudiences={activeAudiences}\n analyticsData={analyticsData}\n imageCdnUrl={config.data.imageCdnUrl}\n resourceThumbnailFallbackImageUrl={ImageUrls.Fallbacks.RESOURCE_THUMBNAIL}\n emptyImageUrl={isTeacherOnly ? ImageUrls.EmptyStates.Topics.TEACHER_ONLY : ImageUrls.EmptyStates.Topics.TOPIC}\n isComingSoon={isComingSoon}\n showFollowButtonSpinner={showFollowButtonSpinner}\n comingSoonImageUrl={ImageUrls.EmptyStates.Topics.COMING_SOON}\n appLinks={{\n ...appLinks,\n signUp: SignUpHelper.getSignUpAppLink,\n widgetWizard: () => null,\n previewQuestions: interactive => InteractiveHelpers.getPreviewQuestionsAppLink(interactive)\n }}\n isPreviewing={isPreviewing}\n isViewCurrentPresentation={isViewCurrentPresentation}\n canFollowSubjects={canFollowSubjects}\n onSubmitFeedback={\n hasPermissions(PermissionName.CanSubmitFeedback) &&\n onSubmitFeedback\n }\n tableOfContentsId={props.queryParams.tocId}\n lazyLoad={!SeoHelper.isBot()}\n moviesAndTv={props.queryParams.mtv}\n isTeacherOnly={isTeacherOnly}\n specialEvent={specialEvent.data}\n isBot={SeoHelper.isBot()}\n hasTopicDirectoryDashboard={hasTopicDirectoryDashboard}\n hasTopicCurriculumDashboard={hasTopicCurriculumDashboard}\n tab={TopicsHelper.getActiveTopicTab(classification.data, props.targetType)}\n // just... one... more.. prop....\n settings={settings}\n isTertiaryCustomerWithoutExchange={isTertiary && !products?.hasProduct(ProductId.Exchange)}\n commonVideoProps={commonVideoProps}\n />\n </div>\n </VideoActionsContext.Provider>\n );\n}\n","import { useSettings } from 'libs/shared/hooks/useSettings';\nimport { DashboardTargetType } from 'libs/shared/interfaces';\n\nimport { useFetchCuratedDashboard } from 'shared/utils/DashboardHelper';\n\nimport { ClassificationViewQueryParams } from '../views/classification/ClassificationViewUtils';\n\nexport function useFetchClassificationDashboard(\n id: string,\n queryParams: ClassificationViewQueryParams,\n targetType: DashboardTargetType\n) {\n const { hasTopicDirectories, hasTopicVideoListFeature } = useSettings(null);\n\n const {\n dashboard: curatedTopicDashboard,\n isPreviewing,\n isTeacherOnly\n } = useFetchCuratedDashboard({\n classificationId: id,\n queryParams: queryParams,\n targetType: DashboardTargetType.Classification\n });\n\n const { dashboard: directoryDashboard } = useFetchCuratedDashboard({\n classificationId: id,\n queryParams: queryParams,\n targetType: DashboardTargetType.ClassificationDirectory\n });\n\n const { dashboard: curriculumDashboard } = useFetchCuratedDashboard({\n classificationId: id,\n queryParams: queryParams,\n targetType: DashboardTargetType.ClassificationCurriculum\n });\n\n function getDashboard() {\n switch (targetType) {\n case DashboardTargetType.Classification:\n return curatedTopicDashboard;\n case DashboardTargetType.ClassificationDirectory:\n return directoryDashboard;\n case DashboardTargetType.ClassificationCurriculum:\n return curriculumDashboard;\n }\n }\n\n return {\n dashboard: getDashboard(),\n hasTopicDirectoryDashboard: hasTopicDirectories && !!directoryDashboard.data,\n hasTopicCurriculumDashboard: hasTopicVideoListFeature && !!curriculumDashboard.data,\n isTeacherOnly,\n isPreviewing\n };\n}","// extracted by mini-css-extract-plugin\nexport default {\"pillTabSelector\":\"Hdi6o\",\"tab\":\"RvNxr\",\"minWidth\":\"GHSz9\",\"radiusSmall\":\"VhJJa\",\"tabLink\":\"WFyvo\"};"],"names":["CalendarRequests","calendarEvents","from","to","presentationId","url","publicUrl","key","nextTopicSpecialEvent","classificationId","params","limit","Date","objectType","formatData","events","getPhrase","LanguageService","AudienceItem","props","audience","highlight","setAudience","isDisabled","extraClasses","colourClass","getColourClass","cursorClass","className","type","onClick","FunctionHelper","role","name","disabled","split","map","s","charAt","toUpperCase","substring","join","defaultProps","DashboardStatusConfig","Dashboard","svgName","svgColorClassName","actionName","statusName","getClassName","status","darkMode","wrapperClassName","DashboardStatusBadge","SvgContainer","PreviewBanner","EmojiText","emoji","namespace","BackButton","textShadow","backToName","appLink","color","backPhrase","colorClass","textShadowClass","AppLink","size","S","RATIO","width","height","getSizeClass","heading","length","BannerHeader","banner","imageCdnUrl","actions","sortComponent","blockColourClass","specialEvent","portalContainerContext","BannerPortalContext","imageWidth","useBreakpoints","xxl","specialEventIsToday","showComingSoon","today","DateHelper","endDate","startDate","imageOptions","ratio","resizeType","ImageHelper","fallbackBaseUrl","fallbackCategoryName","containerProps","bannerClassName","style","backgroundImage","DetailsComponent","detailsComponent","logoFallbackBgClassName","getBgColorClass","PortalHelper","backButtonAppLink","backButtonText","backButtonClasses","alignLogoLeft","logo","GenericCalendarDate","body","text","month","getSpecialEventMonthText","theme","calendarTheme","Text","phrase","ComingSoonTag","LazyImage","src","backgroundColor","logoBgColour","Actions","actionsDropdownClassName","container","prevProps","nextProps","PartialBannerHeader","TabContents","tab","count","data","PillTabSelector","ref","containerRef","borderRadius","listClassName","tabs","index","active","analyticsData","analyticsOptions","onSelect","onSelectTab","FeedbackType","defaultErrors","notFound","forbidden","rating","yearLevel","region","privacy","badRequest","internalServerError","handleHttpError","info","customErrorMap","ignoreMap","statusCode","errorMap","FeedbackRequests","submitFeedback","requestData","formValues","generateCacheKey","flightObjs","obj","useHandleObjectError","_flightObjs","customErrors","ignoreErrors","Array","isArray","useEffect","forEach","useBreadcrumbs","current","match","breadcrumbs","useBuilder","COUNTRY_CODE_TAGS","C","FeedbackFormHelper","getUserInfo","currentUser","customer","id","username","email","userType","customerId","cvcId","crmId","customerName","instanceRegion","contentRegion","firstName","givenName","lastName","familyName","mapCountryCodeToTag","countryCode","toLowerCase","getTags","product","hasStudentExperience","extraTags","tags","push","countryCodeTag","categorizeFiles","files","reduce","result","file","fileInfo","get","videoUrls","imageUrls","Separator","ClassificationHeaderDetails","TopicsHelper","classification","dashboardVideoCount","childDashboardVideoCount","dashboardResourceCount","childDashboardResourceCount","childClassificationCount","videoCount","resourceCount","options","toLocaleString","smartCount","CuratedClassificationEmptyState","isArchived","dashboard","value","EmptyState","imageUrl","altText","isReadonly","Tooltip","title","spanHack","addWidgetApplink","icon","TableOfContentsMobile","isExpanded","setIsExpanded","TableOfContentsList","items","widgets","widget","tocIndentation","metadata","activeId","setControlledId","getAppLink","onItemClick","IconButton","actionType","entity","location","AnalyticsHelper","TableOfContents","TableOfContentsContainer","currentAppLink","ContextService","tocId","isSmallScreen","TeacherOnlyEmptyState","ctaAppLink","ClassificationComingSoon","isFollowing","followers","showSignUp","canFollowSubjects","ActionButton","onToggleFollow","showSpinner","showFollowButtonSpinner","signUpAppLink","workflowPhase","descriptor","SignUp","tag","AudienceFilter","audiences","activeAudiences","setActiveAudiences","SharedViewModelKeys","undefined","storage","onToggleAudience","isSelected","otherParams","activeAudienceNames","a","filter","ObjectHelper","Object","assign","replace","disablePersist","tooltip","masterId","find","aa","keys","DivButton","PARTIAL_AUDIENCES","PartialLoadingHelper","numItems","PartialAudienceFilter","idx","dangerouslySetInnerHTML","__html","ClassificationDashboardAudiences","getTabs","breakpoints","activeTab","isHighlighting","showText","lg","xl","xs","appLinks","classificationName","presentation","presentationDescription","description","classificationDirectory","classificationCurriculum","ClassificationTabs","useDirectoryTabProductTipSwitcher","setProductTipRef","el","ClassificationDashboardNav","isEmpty","hideAudiences","isComingSoon","AudienceHelper","canShowTabs","hasTopicDirectoryDashboard","externalMetadata","isCurated","hasTopicCurriculumDashboard","getTopRowClass","Breadcrumbs","getBreadcrumbs","getBottomRowClass","disableAudiences","audienceTooltip","isViewingCurrentPresentation","isHeadingWidget","widgetId","WidgetTypeId","templateId","WidgetTemplate","isTopicWidget","ClassificationDashboard","isSystemGeneratedDashboard","systemGeneratedVideoWidget","systemGeneratedVideoContent","DashboardRequests","videoList","content","videoListWidgetId","ArrayHelper","useGetTopicsWidgets","headingRef","Set","initialEmptyWidgets","acc","emptyWidgets","setEmptyWidgets","tableOfContentsId","controlledId","tableOfContentActiveId","setTableOfContentActiveId","headingElements","getWidgetContentRequest","widgetTypeId","template","curriculums","preferredCurriculum","useTableOfContentsScroll","useTableOfContentsActiveHeading","setActiveId","showEmptyState","isTeacherOnly","isPreviewing","values","every","state","onSetIsEmpty","newEmptyState","currentWidget","isHeadingEmpty","subWidgetIndex","headingSubWidget","hideWidget","getWidgetHeading","previousWidget","target","widgetsInTableOfContents","w","showInTableOfContents","isTopicOnlyDashboard","shouldShowTableOfContents","shouldShowSideTableOfContents","shouldShowTopicCounts","settings","hasTopicDirectories","isTertiaryCustomerWithoutExchange","moviesAndTv","getBannerActions","background","border","isViewCurrentPresentation","comingSoonImageUrl","hasLocalPermissions","signUp","clickable","WidgetContainerView","widgetCollection","headingElementRef","getContentRequest","setIsEmpty","isScrollToTargetWidget","scrollToWidgetId","onSubmitFeedback","isBot","hasTableOfContents","lazyLoad","dashboardTarget","widgetIndex","hasPermissions","contentType","resourceThumbnailFallbackImageUrl","onToggleFollowClassification","isEditing","commonVideoProps","limitTotalItems","seeMoreLink","onClickRemoveItem","badgeComponent","WidgetHeader","VideoList","videos","getVideoAppLink","video","opts","videoType","contextId","includeContext","presentationAudiences","getPreviewQuestionsAppLink","previewQuestions","emptyImageUrl","widgetWizard","allTopics","PartialClassificationDashboard","endpoints","ids","UrlHelper","FollowRequests","follow","userId","success","error","HttpVerbs","invalidationKeys","unfollow","TopicNotFoundError","application","action","ErrorPageError","CuratedClassificationView","queryParams","setShowFollowButtonSpinner","alerts","fetchAsync","usePermissions","useSettings","config","ConfigRequests","UserRequests","useCurationStudio","openInCurationStudioLabel","isUserCurator","getOpenInCurationStudioLink","useCurriculums","PermissionName","isAuthenticated","CustomerRequests","ClassificationRequests","AudienceRequests","libraries","LibraryRequests","usePresentation","activePresentation","availablePresentations","canAccessPresentation","path","targetType","hasTopicVideoListFeature","curatedTopicDashboard","directoryDashboard","curriculumDashboard","getDashboard","useFetchClassificationDashboard","isTertiary","useIsTertiary","products","regionAlternatives","preferredRegionAlternative","SeoHelper","useSetPageMetadata","PageMetadataHelper","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","canonicalLink","stripPresentationSlug","customAppLink","ClassificationAppLinkHelper","hrefTransformer","allowIndexing","hrefLang","useDeepLinks","app","isMobile","useCommonVideoProps","locationContext","mtv","videoActions","useVideoActions","ClassificationStatus","activeAudienceIds","followedClassification","isTogglingCurrentTopic","toString","request","then","presentationName","currentClassificationId","currentClassificationName","followingCurrentClassification","hasCompleted","VideoActionsContext","widgetTemplate","LibraryHelper","hasTwig","hasTigtag","hideTigTag","hideTwig","label","button","href","MasterType","openInNewTab","ImageUrls","SignUpHelper","interactive","InteractiveHelper","feedback","user","ProductId","reaction","dashboardName","dashboardId","currentPageUrl","promise","feedbackType","hasProduct"],"sourceRoot":""}