@clickview/lite 0.76.0-rc.1 → 0.76.0-rc.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"scripts/6948-bb65fe4173-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/apps/upload/utils/FileExtensionsHelper.ts","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 _ from 'underscore';\n\n/**\n * This are kept as separate variables for when we eventually need a single group of them.\n * For example when we add image upload support.\n */\n\nconst pdfExtensions = ['pdf'];\nconst docExtensions = [ 'doc', 'docx', 'dotx', 'dot', 'rtf', 'docm', 'odt' ];\nconst textExtensions = [ 'csv', 'txt' ];\nconst excelExtensions = [ 'xls', 'xlt', 'xlsx' ];\nconst imageExtensions = [ 'jpg', 'tif', 'png', 'bmp', 'gif', 'jpeg' ];\nconst videoMimeType = 'video/*';\nconst archiveExtensions = [ 'zip', 'rar' ];\nconst powerPointExtensions = [ 'ppt', 'pot', 'pps', 'pptx' ];\n\nconst subtitleExtensions = ['srt'];\n\nconst FileExtensions = {\n IMAGES: `.${imageExtensions.join(',.')}`,\n VIDEO: videoMimeType,\n MIXED_MEDIA: `.${imageExtensions.join(',.')},${videoMimeType}`,\n RESOURCES: `.${[\n ...docExtensions,\n ...excelExtensions,\n ...powerPointExtensions,\n ...pdfExtensions,\n ...textExtensions,\n ...imageExtensions,\n ...archiveExtensions\n ].join(',.')}`,\n SUBTITLES: `.${subtitleExtensions.join(',.')}`\n};\n\nconst FileExtensionHelper = {\n getResourceType(extension: string): string {\n const ext = extension.toLowerCase();\n\n if (_.contains(docExtensions, ext)) return 'document';\n if (_.contains(excelExtensions, ext)) return 'excel';\n if (_.contains(powerPointExtensions, ext)) return 'powerpoint';\n if (_.contains(pdfExtensions, ext)) return 'pdf';\n\n if (_.contains(textExtensions, ext)) return 'text';\n if (_.contains(imageExtensions, ext)) return 'image';\n if (_.contains(archiveExtensions, ext)) return 'archive';\n if (_.contains(subtitleExtensions, ext)) return 'subtitle';\n\n return '';\n }\n};\n\nexport { FileExtensions, FileExtensionHelper };","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 { InstanceRegion } from 'libs/shared/enums/InstanceRegion';\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\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 mapInstanceRegionToTag: (instanceRegion: InstanceRegion): string => {\n switch (instanceRegion) {\n case InstanceRegion.AU:\n return 'au';\n case InstanceRegion.NZ:\n return 'nz';\n case InstanceRegion.UK:\n return 'uk';\n case InstanceRegion.US:\n return 'us';\n }\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 regionTag = FeedbackFormHelper.mapInstanceRegionToTag(currentUser.instanceRegion);\n \n if (regionTag)\n tags.push(regionTag);\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: () => `/api/domain/v1/subjects/classifications/following`,\n unfollow: (ids: string[]) => UrlHelper.urlBuilder('/api/domain/v1/subjects/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 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(classification.data)\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","pdfExtensions","docExtensions","textExtensions","excelExtensions","imageExtensions","videoMimeType","archiveExtensions","powerPointExtensions","subtitleExtensions","FileExtensions","IMAGES","VIDEO","MIXED_MEDIA","RESOURCES","SUBTITLES","FileExtensionHelper","getResourceType","extension","ext","toLowerCase","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","FeedbackFormHelper","getUserInfo","currentUser","customer","id","username","email","userType","customerId","cvcId","crmId","customerName","instanceRegion","contentRegion","firstName","givenName","lastName","familyName","mapInstanceRegionToTag","getTags","product","hasStudentExperience","extraTags","tags","push","regionTag","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","useSetPageMetadata","PageMetadataHelper","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","canonicalLink","SeoHelper","stripPresentationSlug","customAppLink","ClassificationAppLinkHelper","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-ecc082ff3e-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/apps/upload/utils/FileExtensionsHelper.ts","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 _ from 'underscore';\n\n/**\n * This are kept as separate variables for when we eventually need a single group of them.\n * For example when we add image upload support.\n */\n\nconst pdfExtensions = ['pdf'];\nconst docExtensions = [ 'doc', 'docx', 'dotx', 'dot', 'rtf', 'docm', 'odt' ];\nconst textExtensions = [ 'csv', 'txt' ];\nconst excelExtensions = [ 'xls', 'xlt', 'xlsx' ];\nconst imageExtensions = [ 'jpg', 'tif', 'png', 'bmp', 'gif', 'jpeg' ];\nconst videoMimeType = 'video/*';\nconst archiveExtensions = [ 'zip', 'rar' ];\nconst powerPointExtensions = [ 'ppt', 'pot', 'pps', 'pptx' ];\n\nconst subtitleExtensions = ['srt'];\n\nconst FileExtensions = {\n IMAGES: `.${imageExtensions.join(',.')}`,\n VIDEO: videoMimeType,\n MIXED_MEDIA: `.${imageExtensions.join(',.')},${videoMimeType}`,\n RESOURCES: `.${[\n ...docExtensions,\n ...excelExtensions,\n ...powerPointExtensions,\n ...pdfExtensions,\n ...textExtensions,\n ...imageExtensions,\n ...archiveExtensions\n ].join(',.')}`,\n SUBTITLES: `.${subtitleExtensions.join(',.')}`\n};\n\nconst FileExtensionHelper = {\n getResourceType(extension: string): string {\n const ext = extension.toLowerCase();\n\n if (_.contains(docExtensions, ext)) return 'document';\n if (_.contains(excelExtensions, ext)) return 'excel';\n if (_.contains(powerPointExtensions, ext)) return 'powerpoint';\n if (_.contains(pdfExtensions, ext)) return 'pdf';\n\n if (_.contains(textExtensions, ext)) return 'text';\n if (_.contains(imageExtensions, ext)) return 'image';\n if (_.contains(archiveExtensions, ext)) return 'archive';\n if (_.contains(subtitleExtensions, ext)) return 'subtitle';\n\n return '';\n }\n};\n\nexport { FileExtensions, FileExtensionHelper };","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 { InstanceRegion } from 'libs/shared/enums/InstanceRegion';\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\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 mapInstanceRegionToTag: (instanceRegion: InstanceRegion): string => {\n switch (instanceRegion) {\n case InstanceRegion.AU:\n return 'au';\n case InstanceRegion.NZ:\n return 'nz';\n case InstanceRegion.UK:\n return 'uk';\n case InstanceRegion.US:\n return 'us';\n }\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 regionTag = FeedbackFormHelper.mapInstanceRegionToTag(currentUser.instanceRegion);\n \n if (regionTag)\n tags.push(regionTag);\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 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(classification.data)\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","pdfExtensions","docExtensions","textExtensions","excelExtensions","imageExtensions","videoMimeType","archiveExtensions","powerPointExtensions","subtitleExtensions","FileExtensions","IMAGES","VIDEO","MIXED_MEDIA","RESOURCES","SUBTITLES","FileExtensionHelper","getResourceType","extension","ext","toLowerCase","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","FeedbackFormHelper","getUserInfo","currentUser","customer","id","username","email","userType","customerId","cvcId","crmId","customerName","instanceRegion","contentRegion","firstName","givenName","lastName","familyName","mapInstanceRegionToTag","getTags","product","hasStudentExperience","extraTags","tags","push","regionTag","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","useSetPageMetadata","PageMetadataHelper","phraseContext","phraseHandler","titlePhrase","descriptionPhrase","canonicalLink","SeoHelper","stripPresentationSlug","customAppLink","ClassificationAppLinkHelper","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":""}