@clickview/exchange 0.62.0-rc.0 → 0.62.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/.vite/manifest.json +549 -549
  2. package/dist/bundles.json +1 -1
  3. package/dist/css/Crtlho0p.chunk.css +8 -0
  4. package/dist/en.json +1 -1
  5. package/dist/scripts/{Dg-h5qnR.chunk.js → 0uwnPAi2.chunk.js} +2 -2
  6. package/dist/scripts/{Dg-h5qnR.chunk.js.map → 0uwnPAi2.chunk.js.map} +1 -1
  7. package/dist/scripts/{CgGl8jzo.chunk.js → 6f-CHYL3.chunk.js} +2 -2
  8. package/dist/scripts/{CgGl8jzo.chunk.js.map → 6f-CHYL3.chunk.js.map} +1 -1
  9. package/dist/scripts/{CkH6ird3.chunk.js → B09qwiFG.chunk.js} +2 -2
  10. package/dist/scripts/{CkH6ird3.chunk.js.map → B09qwiFG.chunk.js.map} +1 -1
  11. package/dist/scripts/{BRQhDr-02.chunk.js → B0uOvqjG2.chunk.js} +2 -2
  12. package/dist/scripts/{BRQhDr-02.chunk.js.map → B0uOvqjG2.chunk.js.map} +1 -1
  13. package/dist/scripts/{ZSP3Vfha2.chunk.js → B8BobN3r2.chunk.js} +2 -2
  14. package/dist/scripts/{ZSP3Vfha2.chunk.js.map → B8BobN3r2.chunk.js.map} +1 -1
  15. package/dist/scripts/{BHKm8WQq2.chunk.js → B8wHzPHI2.chunk.js} +2 -2
  16. package/dist/scripts/{BHKm8WQq2.chunk.js.map → B8wHzPHI2.chunk.js.map} +1 -1
  17. package/dist/scripts/{CeCXhgoJ.chunk.js → BAIdKirt.chunk.js} +2 -2
  18. package/dist/scripts/{CeCXhgoJ.chunk.js.map → BAIdKirt.chunk.js.map} +1 -1
  19. package/dist/scripts/{Ct8ETEOn2.chunk.js → BAwP70HI2.chunk.js} +2 -2
  20. package/dist/scripts/{Ct8ETEOn2.chunk.js.map → BAwP70HI2.chunk.js.map} +1 -1
  21. package/dist/scripts/{YGLkoFLc.chunk.js → BEv09vqz.chunk.js} +2 -2
  22. package/dist/scripts/{YGLkoFLc.chunk.js.map → BEv09vqz.chunk.js.map} +1 -1
  23. package/dist/scripts/{uPFXIvcK2.chunk.js → BLs3APIS2.chunk.js} +2 -2
  24. package/dist/scripts/{uPFXIvcK2.chunk.js.map → BLs3APIS2.chunk.js.map} +1 -1
  25. package/dist/scripts/{D9zlZIWi2.chunk.js → BP0LMV9S2.chunk.js} +2 -2
  26. package/dist/scripts/{D9zlZIWi2.chunk.js.map → BP0LMV9S2.chunk.js.map} +1 -1
  27. package/dist/scripts/{CqNKzFA4.chunk.js → BPttZx0-.chunk.js} +2 -2
  28. package/dist/scripts/{CqNKzFA4.chunk.js.map → BPttZx0-.chunk.js.map} +1 -1
  29. package/dist/scripts/{B9Rb6IIb.chunk.js → BQk9Mhlr.chunk.js} +2 -2
  30. package/dist/scripts/{B9Rb6IIb.chunk.js.map → BQk9Mhlr.chunk.js.map} +1 -1
  31. package/dist/scripts/{CYUx40jk.chunk.js → BXIfsdxg.chunk.js} +2 -2
  32. package/dist/scripts/{CYUx40jk.chunk.js.map → BXIfsdxg.chunk.js.map} +1 -1
  33. package/dist/scripts/{CvQQNf_J2.chunk.js → B_P4D3Hf2.chunk.js} +2 -2
  34. package/dist/scripts/{CvQQNf_J2.chunk.js.map → B_P4D3Hf2.chunk.js.map} +1 -1
  35. package/dist/scripts/{Dp0gbhZx2.chunk.js → BgskDBpT2.chunk.js} +2 -2
  36. package/dist/scripts/{Dp0gbhZx2.chunk.js.map → BgskDBpT2.chunk.js.map} +1 -1
  37. package/dist/scripts/{Nx0q4bij.chunk.js → BhOZYAZn.chunk.js} +2 -2
  38. package/dist/scripts/{Nx0q4bij.chunk.js.map → BhOZYAZn.chunk.js.map} +1 -1
  39. package/dist/scripts/{CKrB9r9w.chunk.js → Bn9ROglk.chunk.js} +2 -2
  40. package/dist/scripts/{CKrB9r9w.chunk.js.map → Bn9ROglk.chunk.js.map} +1 -1
  41. package/dist/scripts/{Ds3cFntF2.chunk.js → Bo8PhXY12.chunk.js} +3 -3
  42. package/dist/scripts/{Ds3cFntF2.chunk.js.map → Bo8PhXY12.chunk.js.map} +1 -1
  43. package/dist/scripts/{Fu0bLEzl2.chunk.js → BrVyRSUS2.chunk.js} +2 -2
  44. package/dist/scripts/{Fu0bLEzl2.chunk.js.map → BrVyRSUS2.chunk.js.map} +1 -1
  45. package/dist/scripts/{CeHHO1Hv.chunk.js → BxLgTmMl.chunk.js} +2 -2
  46. package/dist/scripts/{CeHHO1Hv.chunk.js.map → BxLgTmMl.chunk.js.map} +1 -1
  47. package/dist/scripts/{BPgKK-d32.chunk.js → Bxsu4S752.chunk.js} +2 -2
  48. package/dist/scripts/{BPgKK-d32.chunk.js.map → Bxsu4S752.chunk.js.map} +1 -1
  49. package/dist/scripts/{B0VKYPiu.chunk.js → C-PORBUs.chunk.js} +2 -2
  50. package/dist/scripts/{B0VKYPiu.chunk.js.map → C-PORBUs.chunk.js.map} +1 -1
  51. package/dist/scripts/{RiPZGw_q2.chunk.js → C1StI3Bl2.chunk.js} +2 -2
  52. package/dist/scripts/{RiPZGw_q2.chunk.js.map → C1StI3Bl2.chunk.js.map} +1 -1
  53. package/dist/scripts/{DoTtsl0X.chunk.js → C6Hr-vqw.chunk.js} +2 -2
  54. package/dist/scripts/{DoTtsl0X.chunk.js.map → C6Hr-vqw.chunk.js.map} +1 -1
  55. package/dist/scripts/{UjMbny4R.chunk.js → CBnNAkzx.chunk.js} +2 -2
  56. package/dist/scripts/{UjMbny4R.chunk.js.map → CBnNAkzx.chunk.js.map} +1 -1
  57. package/dist/scripts/{DyRGf1o8.chunk.js → CFkqPGiT.chunk.js} +2 -2
  58. package/dist/scripts/{DyRGf1o8.chunk.js.map → CFkqPGiT.chunk.js.map} +1 -1
  59. package/dist/scripts/{Xs1Bv1h-.chunk.js → CKD2j1rw.chunk.js} +2 -2
  60. package/dist/scripts/{Xs1Bv1h-.chunk.js.map → CKD2j1rw.chunk.js.map} +1 -1
  61. package/dist/scripts/{aDegERgV2.chunk.js → CSKzCsLv2.chunk.js} +2 -2
  62. package/dist/scripts/{aDegERgV2.chunk.js.map → CSKzCsLv2.chunk.js.map} +1 -1
  63. package/dist/scripts/{DVVx1aiS2.chunk.js → CZgaUoHE2.chunk.js} +2 -2
  64. package/dist/scripts/{DVVx1aiS2.chunk.js.map → CZgaUoHE2.chunk.js.map} +1 -1
  65. package/dist/scripts/{B6mSouu5.chunk.js → C_7tv1r9.chunk.js} +2 -2
  66. package/dist/scripts/{B6mSouu5.chunk.js.map → C_7tv1r9.chunk.js.map} +1 -1
  67. package/dist/scripts/{DtYC8Udi2.chunk.js → C_jUsStb2.chunk.js} +2 -2
  68. package/dist/scripts/{DtYC8Udi2.chunk.js.map → C_jUsStb2.chunk.js.map} +1 -1
  69. package/dist/scripts/{BOvQpQ21.chunk.js → CdNTKjPA.chunk.js} +2 -2
  70. package/dist/scripts/{BOvQpQ21.chunk.js.map → CdNTKjPA.chunk.js.map} +1 -1
  71. package/dist/scripts/{C7OCN_w_.chunk.js → ChDwbV8F.chunk.js} +2 -2
  72. package/dist/scripts/{C7OCN_w_.chunk.js.map → ChDwbV8F.chunk.js.map} +1 -1
  73. package/dist/scripts/{CKUk2HqE.chunk.js → Cq-TpkxJ.chunk.js} +2 -2
  74. package/dist/scripts/{CKUk2HqE.chunk.js.map → Cq-TpkxJ.chunk.js.map} +1 -1
  75. package/dist/scripts/{o2htB_49.chunk.js → CrCX606H.chunk.js} +2 -2
  76. package/dist/scripts/{o2htB_49.chunk.js.map → CrCX606H.chunk.js.map} +1 -1
  77. package/dist/scripts/{D0H6Hjd-2.chunk.js → CrDpB82d2.chunk.js} +2 -2
  78. package/dist/scripts/{D0H6Hjd-2.chunk.js.map → CrDpB82d2.chunk.js.map} +1 -1
  79. package/dist/scripts/{DBKlntFN2.chunk.js → Czivka682.chunk.js} +2 -2
  80. package/dist/scripts/{DBKlntFN2.chunk.js.map → Czivka682.chunk.js.map} +1 -1
  81. package/dist/scripts/{eLmgigsW.chunk.js → DEP_Z-S0.chunk.js} +2 -2
  82. package/dist/scripts/{eLmgigsW.chunk.js.map → DEP_Z-S0.chunk.js.map} +1 -1
  83. package/dist/scripts/{cIPkkuhG.chunk.js → DQBoqkL7.chunk.js} +2 -2
  84. package/dist/scripts/{cIPkkuhG.chunk.js.map → DQBoqkL7.chunk.js.map} +1 -1
  85. package/dist/scripts/{BV2vTX2L.chunk.js → DeXP2wHV.chunk.js} +2 -2
  86. package/dist/scripts/{BV2vTX2L.chunk.js.map → DeXP2wHV.chunk.js.map} +1 -1
  87. package/dist/scripts/{C1u2qBZg2.chunk.js → Df82DFJ62.chunk.js} +2 -2
  88. package/dist/scripts/{C1u2qBZg2.chunk.js.map → Df82DFJ62.chunk.js.map} +1 -1
  89. package/dist/scripts/{Co_6cSBX2.chunk.js → DgrEIxhT2.chunk.js} +2 -2
  90. package/dist/scripts/{Co_6cSBX2.chunk.js.map → DgrEIxhT2.chunk.js.map} +1 -1
  91. package/dist/scripts/{CRHkMr9_2.chunk.js → DhT0tpZm2.chunk.js} +2 -2
  92. package/dist/scripts/{CRHkMr9_2.chunk.js.map → DhT0tpZm2.chunk.js.map} +1 -1
  93. package/dist/scripts/{CUdaR862.chunk.js → Dhe09-jE.chunk.js} +2 -2
  94. package/dist/scripts/{CUdaR862.chunk.js.map → Dhe09-jE.chunk.js.map} +1 -1
  95. package/dist/scripts/{BijIuzIs2.chunk.js → DhtgaF-y2.chunk.js} +2 -2
  96. package/dist/scripts/{BijIuzIs2.chunk.js.map → DhtgaF-y2.chunk.js.map} +1 -1
  97. package/dist/scripts/{BsSKrRku2.chunk.js → Div1wl-R2.chunk.js} +2 -2
  98. package/dist/scripts/{BsSKrRku2.chunk.js.map → Div1wl-R2.chunk.js.map} +1 -1
  99. package/dist/scripts/{CKNdXwxe2.chunk.js → DjuXXgD-2.chunk.js} +2 -2
  100. package/dist/scripts/{CKNdXwxe2.chunk.js.map → DjuXXgD-2.chunk.js.map} +1 -1
  101. package/dist/scripts/{DBJfKQKx.chunk.js → Dkazht4Q.chunk.js} +2 -2
  102. package/dist/scripts/{DBJfKQKx.chunk.js.map → Dkazht4Q.chunk.js.map} +1 -1
  103. package/dist/scripts/{D5qMnGHT2.chunk.js → DmmZ2XbB2.chunk.js} +2 -2
  104. package/dist/scripts/{D5qMnGHT2.chunk.js.map → DmmZ2XbB2.chunk.js.map} +1 -1
  105. package/dist/scripts/{CWsmm40y.chunk.js → Dr35AMvf.chunk.js} +2 -2
  106. package/dist/scripts/{CWsmm40y.chunk.js.map → Dr35AMvf.chunk.js.map} +1 -1
  107. package/dist/scripts/{CyAM5o2e.chunk.js → HgLS_KfH.chunk.js} +2 -2
  108. package/dist/scripts/{CyAM5o2e.chunk.js.map → HgLS_KfH.chunk.js.map} +1 -1
  109. package/dist/scripts/{zp5MUThO.chunk.js → W8Q7Z6fd.chunk.js} +2 -2
  110. package/dist/scripts/{zp5MUThO.chunk.js.map → W8Q7Z6fd.chunk.js.map} +1 -1
  111. package/dist/scripts/{NInuYe7b2.chunk.js → XWykPl9h2.chunk.js} +2 -2
  112. package/dist/scripts/{NInuYe7b2.chunk.js.map → XWykPl9h2.chunk.js.map} +1 -1
  113. package/dist/scripts/{BggsU83p2.chunk.js → _3n_0ch72.chunk.js} +2 -2
  114. package/dist/scripts/{BggsU83p2.chunk.js.map → _3n_0ch72.chunk.js.map} +1 -1
  115. package/dist/scripts/{app-DDrsm5nt.js → app-CgkYY4K0.js} +3 -3
  116. package/dist/scripts/app-CgkYY4K0.js.map +1 -0
  117. package/dist/scripts/{DeevL6eQ.chunk.js → go6zFmPK.chunk.js} +2 -2
  118. package/dist/scripts/{DeevL6eQ.chunk.js.map → go6zFmPK.chunk.js.map} +1 -1
  119. package/dist/scripts/{BJxTZJOX.chunk.js → p5-1Ey-R.chunk.js} +2 -2
  120. package/dist/scripts/{BJxTZJOX.chunk.js.map → p5-1Ey-R.chunk.js.map} +1 -1
  121. package/dist/scripts/{B0hNKKDw2.chunk.js → qrcrWbQJ2.chunk.js} +2 -2
  122. package/dist/scripts/{B0hNKKDw2.chunk.js.map → qrcrWbQJ2.chunk.js.map} +1 -1
  123. package/package.json +1 -1
  124. package/dist/scripts/app-DDrsm5nt.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Nx0q4bij.chunk.js","names":[],"sources":["../../../../libs/shared/src/interfaces/models/CalendarEvent.ts","../../../../libs/shared/src/constants/TopicsConstants.ts","../../../../libs/shared/src/apps/search/components/filter-actions/FilterActions.tsx","../../../../libs/shared/src/apps/search/reducers/FilterReducer.tsx","../../../../libs/shared/src/apps/search/components/filter-dropdown-title/FilterDropdownTitle.tsx","../../../../libs/shared/src/apps/search/components/filter-types/checkbox-filter/CheckboxFilterList.tsx","../../../../libs/shared/src/apps/search/components/filter-types/checkbox-filter/CheckboxFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/nested-checkbox-filter/components/NestedFilterOptions.tsx","../../../../libs/shared/src/apps/search/components/filter-types/nested-checkbox-filter/components/SecondLayerOptions.tsx","../../../../libs/shared/src/apps/search/components/filter-types/nested-checkbox-filter/NestedCheckboxFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/switch-filter/SwitchFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/dropdown-filter/DropdownFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/radio-filter/radio-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/radio-filter/RadioFilter.tsx","../../../../libs/shared/src/components/rating-range-selector/RatingRangeSelector.tsx","../../../../libs/shared/src/apps/search/components/filter-types/rating-filter/rating-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/rating-filter/RatingFilter.tsx","../../../../libs/shared/src/apps/search/constants/FilterConstants.ts","../../../../libs/shared/src/apps/search/utils/SourceFilterHelper.ts","../../../../libs/shared/src/enums/CurationTag.ts","../../../../libs/shared/src/enums/CustomerStatus.ts","../../../../libs/shared/src/apps/calendar/constants/SpecialEventTypeLabelMap.ts","../../../../libs/shared/src/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/activation-action-info/BulkUserActivationActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/activation-email-info/BulkUserActivationEmailActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/add-to-classroom-action-info/BulkAddToClassroomActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/change-year-group-action-info/ChangeYearGroupActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/delete-action-info/BulkUserDeleteActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/remove-action-info/BulkUserRemoveActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/reset-email-info/BulkUserResetEmailActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/reset-password-action-info/BulkResetPasswordActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/year-group-rollover-action-info/BulkUserYearGroupRolloverActionInfo.tsx","../../../../libs/shared/src/images/svg/status/CheckCircleSvg.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/user-item-components.module.scss","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/UserStatusBadge.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/BasicUserDetails.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/RoleOrYearGroup.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/UserItemAvatar.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/bulk-user-actions-errored-user-item/BulkUserActionsErroredUserItem.tsx","../../../../libs/shared/src/apps/user-manager/enums/UserManagerClient.ts","../../../../libs/shared/src/context/WizardLayoutContext.tsx","../../../../libs/shared/src/enums/BatchDataType.ts","../../../../libs/shared/src/enums/BatchJobName.ts","../../../../libs/shared/src/enums/BatchJobResultErrorCode.ts","../../../../libs/shared/src/enums/BatchJobType.ts","../../../../libs/shared/src/images/svg/objects/KeySvg.tsx","../../../../libs/shared/src/apps/user-manager/utils/BulkUserActionsHelper.tsx","../../../../libs/shared/src/apps/search/components/filter-types/custom/duration-filter/DurationFilter.tsx","../../../../libs/shared/src/constants/XmasConstants.ts","../../../../libs/shared/src/apps/search/components/filter-types/custom/movies-and-tv-filter/movies-and-tv-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/custom/movies-and-tv-filter/MoviesAndTvFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/grouped-checkbox-filter/GroupedCheckboxFilter.tsx","../../../../libs/shared/src/apps/search/utils/ClassificationFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/DurationFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/PresentationFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/ProductionYearFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/RatingFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/FilterHelper.tsx","../../../../libs/shared/src/apps/search/components/filter-button/filter-button.module.scss","../../../../libs/shared/src/apps/search/components/filter-button/FilterButton.tsx","../../../../libs/shared/src/utils/StateHelper.ts","../../../../libs/shared/src/apps/search/components/filter-button/MoreFiltersButton.tsx","../../../../libs/shared/src/components/tags/PartialTagItem.tsx","../../../../libs/shared/src/components/widgets/hooks/useWidgetKeyboard.ts","../../../../libs/shared/src/enums/CssMeasurement.ts","../../../../libs/shared/src/utils/DragHelper.ts","../../../../libs/shared/src/components/widgets/sliding-list/SlidingListContainer.tsx","../../../../libs/shared/src/images/svg/arrows/ChevronRightSvg.tsx","../../../../libs/shared/src/components/widgets/widget-button/widget-button.module.scss","../../../../libs/shared/src/components/widgets/widget-button/WidgetButton.tsx","../../../../libs/shared/src/enums/WidgetInteraction.ts","../../../../libs/shared/src/hooks/UseResizeListener.ts","../../../../libs/shared/src/components/widgets/dynamic-widget/DynamicWidgetEventHandlers.ts","../../../../libs/shared/src/components/widgets/dynamic-widget/DynamicWidgetReducer.tsx","../../../../libs/shared/src/components/widgets/dynamic-widget/dynamic-widget.module.scss","../../../../libs/shared/src/components/widgets/dynamic-widget/DynamicWidget.tsx","../../../../libs/shared/src/components/widgets/items/tag-widget-item/TagWidgetItem.tsx","../../../../libs/shared/src/apps/search/components/filter-types/tag-filter/tag-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/tag-filter/TagFilter.tsx","../../../../libs/shared/src/apps/search/components/reset-button/ResetButton.tsx","../../../../libs/shared/src/apps/search/components/search-filters/search-filters.module.scss","../../../../libs/shared/src/apps/search/components/search-filters/SearchFilters.tsx"],"sourcesContent":["import { BaseObject, BasePaginatedCollection, Classification, Livestream } from 'libs/shared/interfaces';\n\nexport type CalendarEventType = 'Observance' | 'ReligiousEvent' | 'Holiday' | 'Livestream';\n\nexport enum SpecialEventType {\n Holiday = 'Holiday',\n SportingEvent = 'SportingEvent',\n Observance = 'Observance',\n NaturalDisaster = 'NaturalDisaster',\n HistoricalEvent = 'HistoricalEvent',\n BreakingNews = 'BreakingNews',\n Informal = 'Informal',\n ReligiousEvent = 'ReligiousEvent',\n Livestream = 'Livestream',\n Other = 'Other'\n}\n\nexport enum CalendarEventContentType {\n Classification,\n Livestream\n}\n\nexport enum CalendarEventFrequency {\n Regular = 'Regular',\n Daily = 'Daily',\n Weekly = 'Weekly',\n Monthly = 'Monthly',\n Yearly = 'Yearly'\n}\n\nexport enum CalendarEventStatus {\n Draft = 'Draft',\n Published = 'Published',\n Archived = 'Archived'\n}\n\nexport type CalendarEventContent = Classification | Livestream;\n\nexport interface CalendarEvent<T extends CalendarEventContent = Classification> {\n id: string;\n type: CalendarEventType;\n name: string;\n description?: string;\n startDate: string;\n endDate?: string;\n content: T;\n specialEventId?: string;\n specialEventPolicyId?: string;\n metadata?: {\n objectType: 'Topic' | 'Livestream',\n objectId: string\n };\n}\n\nexport interface SpecialEvent<T extends CalendarEventContent = Classification> {\n id: string;\n name: string;\n description: string;\n policies: SpecialEventPolicy<T>[];\n status: CalendarEventStatus;\n type: SpecialEventType;\n}\n\nexport type SpecialEventCollection<T extends CalendarEventContent = Classification> =\n BasePaginatedCollection<SpecialEvent<T>>;\n\nexport interface SpecialEventPolicy<T extends CalendarEventContent = Classification> extends BaseObject {\n content: T;\n specialEventId: string;\n status: CalendarEventStatus;\n presentationId: string;\n startDate: string;\n endDate: string;\n frequency: CalendarEventFrequency;\n interval: number;\n visible: boolean;\n metadata: {\n objectId: string,\n objectType: 'Topic' | 'Livestream'\n };\n}\n","export const TopicsConstants = {\n MULTI_PRESENTATION_THRESHOLD: 2\n};\n","import * as React from 'react';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'search.filterActions';\n\ninterface FilterActionsProps {\n className?: string;\n onClickReset: () => void;\n onClickApply: () => void;\n active: boolean;\n}\n\nFilterActions.defaultProps = {\n active: false,\n className: ''\n};\n\nexport function FilterActions(props: FilterActionsProps): JSX.Element {\n return (\n <div className={`d-flex justify-content-between ${props.className}`}>\n {props.active ? (\n <DivButton className='text-secondary hover-text-underline cursor-pointer' onClick={props.onClickReset}>\n <Text namespace={namespace} phrase='reset' />\n </DivButton>\n ) : (\n <div className='invisible' />\n )}\n\n <DivButton className='info-link' onClick={props.onClickApply}>\n <Text namespace={namespace} phrase='apply' />\n </DivButton>\n </div>\n );\n}\n","import { createContext } from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { ReducerActions } from 'libs/common/react/interfaces';\n\nimport { FilterIds, FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\n\nexport type FilterState = {\n active: boolean,\n selection?: FilterOption[]\n};\n\nexport type DraftState = {\n [key in FilterIds]?: FilterState;\n};\n\ntype FilterStateHashFilters = {\n [key in FilterIds]: FilterState;\n};\n\nexport type FilterStateHash = FilterStateHashFilters & {\n appLink: Core.AppLink,\n moreFilters?: Omit<FilterStateHash, 'moreFilters'>\n};\n\nexport type FilterActionType = 'update';\n\nexport type FilterPayloadType = {\n filter: SearchFilter,\n state: FilterState\n};\n\n/**\n * Context\n */\ninterface FilterContextType {\n state: FilterStateHash;\n dispatch: React.Dispatch<ReducerActions<FilterActionType>>;\n}\n\nexport const FilterContext = createContext<FilterContextType>(null);\n\n/**\n * Reducer - root level keys should match the filter object's corresponding \"id\" field\n */\nexport function FilterReducer(\n state: FilterStateHash,\n action: ReducerActions<FilterActionType, FilterStateHash>\n): FilterStateHash {\n switch (action.type) {\n case 'update': {\n return action.payload;\n }\n\n default:\n return state;\n }\n}\n","import React from 'react';\n\ninterface FilterDropdownTitleProps {\n id?: string;\n title: string;\n}\n\nexport function FilterDropdownTitle(props: FilterDropdownTitleProps): JSX.Element {\n return (\n <label htmlFor={props.id} className='mb-0'>\n <h3 className='h6 mb-2'>{props.title}</h3>\n </label>\n );\n}\n","import React from 'react';\n\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\n\nimport { FilterOption, MoreFilters, SearchFilter } from '../../../interfaces';\nimport { FilterState } from '../../../reducers';\n\ninterface CheckboxFilterListProps {\n displayOptionsIn2Columns: boolean;\n filter: SearchFilter | MoreFilters;\n draftState: FilterState;\n setDraftState: (state: FilterState) => void;\n options: FilterOption[];\n}\n\nexport function CheckboxFilterList(props: CheckboxFilterListProps): JSX.Element {\n const selections = props.draftState.selection;\n\n function onToggleItem(option: FilterOption, isCurrentlyChecked: boolean): void {\n /**\n * If the item is currently checked, we remove it from the array\n */\n if (isCurrentlyChecked) {\n let indexOfItem: number = -1;\n\n // Find the index of the clicked item\n selections.find((selection, i) => {\n if (indexOfItem > -1)\n return;\n\n if (selection.id.toString() !== option.id.toString())\n return;\n\n indexOfItem = i;\n });\n\n // Return a new array with the clicked item sliced out\n const newItems = [ ...selections.slice(0, indexOfItem), ...selections.slice(indexOfItem + 1) ];\n\n props.setDraftState({ active: !!newItems.length, selection: newItems });\n\n return;\n }\n\n /**\n * If the item wasn't checked, simply push it onto the selections array\n */\n const newItems = [...selections];\n newItems.push(option);\n\n props.setDraftState({\n active: !!newItems.length,\n selection: newItems\n });\n }\n\n const options = props.options.map(option => {\n const isDisabled = props.filter.disabled || option.disabled;\n const isChecked = !!props.draftState.selection.find(s => s.id.toString() === option.id.toString());\n const joinedIds = Array.isArray(option.id) ? option.id.join('_') : option.id;\n \n return (\n <li key={joinedIds} className={`my-1 ${props.displayOptionsIn2Columns ? 'col-md-6 col-12' : ''}`}>\n <Checkbox\n label={option.name}\n name={joinedIds}\n id={joinedIds}\n onChange={() => onToggleItem(option, isChecked)}\n checked={!isDisabled && isChecked}\n isLabelEllipsis={props.displayOptionsIn2Columns}\n disabled={isDisabled}\n />\n </li>\n );\n });\n \n return <ul className={`list-unstyled ${props.displayOptionsIn2Columns ? 'd-flex flex-wrap' : ''}`}>{options}</ul>;\n}\n","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\n\nimport { CheckboxFilterList } from './CheckboxFilterList';\n\nexport function CheckboxFilter(props: FilterProps): JSX.Element {\n const displayOptionsIn2Columns = FilterHelper.displayTwoColumns(props.filter);\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n\n <Form className='mb-3'>\n <CheckboxFilterList\n displayOptionsIn2Columns={displayOptionsIn2Columns}\n options={props.filter.options}\n filter={props.filter}\n draftState={props.draftState}\n setDraftState={props.setDraftState}\n />\n </Form>\n </>\n );\n}\n","import * as React from 'react';\n\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\n\ntype NestedFilterOptionsProps = FilterProps & {\n onToggleItem: (selectedOption: FilterOption, isCurrentlyCheckedOrIndeterminate: boolean) => void,\n onToggleChildItem: (selectedOption: FilterOption, isCurrentlyChecked: boolean, parentOption: FilterOption) => void\n};\n\nexport function NestedFilterOptions(props: NestedFilterOptionsProps): JSX.Element {\n const allOptions: JSX.Element[] = [];\n\n for (const firstLayerOption of props.filter.options) {\n const isFirstLayerOptionDisabled = props.filter.disabled || firstLayerOption.disabled;\n const currentSelection = props.draftState.selection?.find(s => s?.id === firstLayerOption.id);\n const secondLayerOptions = firstLayerOption.secondLayerOptions ?? [];\n const isFirstLayerIndeterminate = getIsFirstLayerIndeterminate(currentSelection, secondLayerOptions);\n const isFirstLayerOptionChecked = !isFirstLayerIndeterminate && !!currentSelection;\n\n // 1st layer\n allOptions.push(\n <Checkbox\n key={firstLayerOption.id}\n label={firstLayerOption.name}\n name={firstLayerOption.id}\n id={firstLayerOption.id}\n indeterminate={isFirstLayerIndeterminate}\n onChange={() => props.onToggleItem(firstLayerOption, isFirstLayerOptionChecked || isFirstLayerIndeterminate)}\n checked={ !isFirstLayerOptionDisabled && isFirstLayerOptionChecked}\n className='my-1'\n disabled={isFirstLayerOptionDisabled}\n />\n );\n\n // 2nd layer\n const showSecondLayer = FilterHelper.hasManyFilterOptions(secondLayerOptions);\n\n showSecondLayer && allOptions.push(\n ...secondLayerOptions.map(secondLayerOption => {\n const isSecondLayerOptionDisabled = isFirstLayerOptionDisabled || secondLayerOption.disabled;\n const isSecondLayerOptionChecked = !!currentSelection?.secondLayerSelection\n ?.find(s => s.id === secondLayerOption.id);\n\n return (\n <Checkbox\n key={secondLayerOption.id}\n label={secondLayerOption.name}\n name={secondLayerOption.id}\n id={secondLayerOption.id}\n onChange={() => props.onToggleChildItem(secondLayerOption, isSecondLayerOptionChecked, firstLayerOption)}\n checked={!isSecondLayerOptionDisabled && isSecondLayerOptionChecked}\n className='my-1 ms-3'\n disabled={isSecondLayerOptionDisabled}\n />\n );\n })\n );\n }\n\n return <>{allOptions}</>;\n}\n\nfunction getIsFirstLayerIndeterminate(currentSelection: FilterOption, secondLayerOptions: FilterOption[]): boolean {\n const hasSecondLayerSelection = currentSelection?.secondLayerSelection?.length > 0;\n const allSecondLayerOptionsChecked = currentSelection?.secondLayerSelection?.length === secondLayerOptions.length;\n return hasSecondLayerSelection && !allSecondLayerOptionsChecked;\n}\n","import * as React from 'react';\n\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\n\ntype SecondLayerOptionProps = FilterProps & {\n onToggleChildItem: (selectedOption: FilterOption, isCurrentlyChecked: boolean, parentOption: FilterOption) => void\n};\n\nexport function SecondLayerOptions(props: SecondLayerOptionProps): JSX.Element {\n for (const firstLayerOption of props.filter.options) {\n const isFirstLayerOptionDisabled = props.filter.disabled || firstLayerOption.disabled;\n const currentSelection = props.draftState.selection?.find(s => s?.id === firstLayerOption.id);\n const secondLayerOptions = firstLayerOption.secondLayerOptions ?? [];\n\n const options = secondLayerOptions.map(secondLayerOption => {\n const isSecondLayerOptionDisabled = isFirstLayerOptionDisabled || secondLayerOption.disabled;\n const isSecondLayerOptionChecked = !!currentSelection?.secondLayerSelection\n ?.find(s => s.id === secondLayerOption.id);\n\n return (\n <Checkbox\n key={secondLayerOption.id}\n label={secondLayerOption.name}\n name={secondLayerOption.id}\n id={secondLayerOption.id}\n onChange={() => props.onToggleChildItem(secondLayerOption, isSecondLayerOptionChecked, firstLayerOption)}\n checked={!isSecondLayerOptionDisabled && isSecondLayerOptionChecked}\n className='my-1'\n disabled={isSecondLayerOptionDisabled}\n />\n );\n });\n\n return <>{options}</>;\n }\n}\n","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\n\nimport { NestedFilterOptions } from './components/NestedFilterOptions';\nimport { SecondLayerOptions } from './components/SecondLayerOptions';\n\nexport function NestedCheckboxFilter(props: FilterProps): JSX.Element {\n const options = props.filter.options;\n\n function onToggleItem(selectedOption: FilterOption, isCurrentlyCheckedOrIndeterminate: boolean): void {\n const { selection } = props.draftState;\n const indexOfOption = selection.findIndex(o => o.id === selectedOption.id);\n\n /**\n * If the item wasn't checked, simply push it onto the selections array\n */\n if (!isCurrentlyCheckedOrIndeterminate) {\n const enabled2ndLayerOptions = (options\n ?.find(o => o.id === selectedOption.id).secondLayerOptions)\n ?.filter(o => !o.disabled);\n\n // Also select all enabled 2nd layer options\n const newSelectedOptionWith2ndLayerOptions =\n { ...selectedOption, secondLayerSelection: enabled2ndLayerOptions };\n\n // Add new option\n if (selection.length === 0 || indexOfOption === -1) {\n const newSelection = [ ...selection, newSelectedOptionWith2ndLayerOptions ];\n\n props.setDraftState({\n active: true,\n selection: newSelection\n });\n\n return;\n }\n\n // Merge selectedItem into selection\n if (indexOfOption !== -1) {\n const newSelection = selection.map(firstLayer => {\n if (firstLayer.id === selectedOption.id) {\n return newSelectedOptionWith2ndLayerOptions;\n }\n\n return firstLayer;\n });\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n\n return;\n }\n }\n\n /**\n * If the item is currently checked, we remove it from the array\n */\n const newSelection = ArrayHelper.removeItemFromIndex(\n selection,\n selection.findIndex(selectionItem => selectionItem.id === selectedOption.id)\n );\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n }\n\n function onToggleChildItem(\n selectedOption: FilterOption,\n isCurrentlyChecked: boolean,\n parentOption: FilterOption\n ): void {\n const { selection } = props.draftState;\n const indexOfParentOption = selection.findIndex(o => o.id === parentOption.id);\n\n if (!isCurrentlyChecked) {\n const newChildSelection = [ ...selection[indexOfParentOption]?.secondLayerSelection ?? [], selectedOption ];\n\n // If no selection/new item is not in selection, add new option\n if (selection.length === 0 || indexOfParentOption === -1) {\n const newParentSelection = {\n ...parentOption,\n secondLayerSelection: newChildSelection\n };\n\n const newSelection = [ ...selection, newParentSelection ];\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n\n return;\n }\n\n // Merge selectedItem into selection\n if (indexOfParentOption !== -1) {\n const newSelection = selection.map(firstLayer => {\n if (firstLayer.id === parentOption.id) {\n return {\n ...firstLayer,\n secondLayerSelection: newChildSelection\n };\n }\n\n return firstLayer;\n });\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n\n return;\n }\n }\n\n // Uncheck child\n let newSelection = selection.map(firstLayer => {\n if (firstLayer.id === parentOption.id) {\n const new2ndLayerSelection = ArrayHelper.removeItem(firstLayer.secondLayerSelection, selectedOption);\n return { ...parentOption, secondLayerSelection: new2ndLayerSelection };\n }\n\n return firstLayer;\n });\n\n // Uncheck parent if no child\n if (newSelection[indexOfParentOption].secondLayerSelection.length === 0) {\n newSelection = ArrayHelper.removeItem(newSelection, parentOption);\n }\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n }\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n <Form className='mb-3'>\n { FilterHelper.hasManyFilterOptions(options) ?\n <NestedFilterOptions onToggleItem={onToggleItem} onToggleChildItem={onToggleChildItem} {...props} /> :\n <SecondLayerOptions onToggleChildItem={onToggleChildItem} {...props} />\n }\n </Form>\n </>\n );\n}\n","import * as React from 'react';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { ToggleSwitch } from 'libs/shared/components/toggle-switch/ToggleSwitch';\n\nexport function SwitchFilter(props: FilterProps): JSX.Element {\n const isActive = props.draftState.active;\n\n function onToggle(): void {\n props.setDraftState({ active: !isActive });\n }\n\n return (\n <>\n <FilterDropdownTitle id={props.filter.id} title={props.filter.name} />\n\n <div className='d-flex align-items-start justify-content-between'>\n <p className='d-inline-block w-75'>{props.filter.description}</p>\n\n <ToggleSwitch id={props.filter.id} disabled={props.filter.disabled} onClick={onToggle} on={isActive} />\n </div>\n </>\n );\n}\n","import React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nexport function DropdownFilter(props: FilterProps): JSX.Element {\n function onSelect(option: FilterOption): void {\n props.setDraftState({\n active: !option.default,\n selection: [option]\n });\n }\n\n return (\n <>\n {props.filter.options.map(option => (\n <Dropdown.Item\n key={option.id}\n onClick={() => onSelect(option)}\n disabled={props.filter.disabled || option.disabled}\n >\n {option.name}\n </Dropdown.Item>\n ))}\n </>\n );\n}\n",":local {\n .radioFilter {\n margin: map-get($spacers, 1) 0;\n\n label::after {\n cursor: pointer;\n }\n }\n}","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nimport styles from './radio-filter.module.scss';\n\nexport function RadioFilter(props: FilterProps): JSX.Element {\n function onSelect(option: FilterOption): void {\n props.setDraftState({\n active: !option.default,\n selection: [option]\n });\n }\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n\n <Form>\n <ul className={`${props.isOnMoreFilters ? 'd-flex flex-wrap' : ''} list-unstyled`}>\n {props.filter.options.map(option => {\n const isDisabled = props.filter.disabled || option.disabled;\n const isSelected = ArrayHelper.first(props.draftState.selection)?.id.toString() === option.id.toString();\n return (\n <li key={option.id} className={`${props.isOnMoreFilters ? 'w-50' : ''}`}>\n <Form.Check\n type='radio'\n label={option.name}\n name={option.id}\n id={option.id}\n value={option.id}\n onChange={() => onSelect(option)}\n checked={!isDisabled && isSelected}\n className={`${styles.radioFilter}`}\n disabled={isDisabled}\n />\n </li>\n );\n })}\n </ul>\n </Form>\n </>\n );\n}\n","import React from 'react';\nimport { ButtonGroup } from 'react-bootstrap';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { useHover } from 'libs/shared/hooks/UseHover';\nimport { Rating, YearGroup } from 'libs/shared/interfaces';\n\ninterface RatingButtonProps {\n rating: Rating;\n isActive: boolean;\n onClick: () => void;\n onHover: (rating: Rating) => void;\n getButtonClasses: (rating: Rating, isActive: boolean, isHovering: boolean) => string;\n disabled?: boolean;\n}\n\nfunction RatingButton(props: RatingButtonProps): JSX.Element {\n const [ ref, isHovering ] = useHover<HTMLDivElement>({ delay: 1 });\n\n React.useEffect(() => {\n props.onHover(isHovering ? props.rating : null);\n }, [isHovering]);\n\n if (!props.rating.code)\n return <></>;\n\n const button = (\n <DivButton\n ref={ref}\n className={props.getButtonClasses(props.rating, props.isActive, isHovering)}\n onClick={props.onClick}\n disabled={props.disabled}\n >\n {props.rating.code}\n </DivButton>\n );\n\n if (props.disabled)\n return button;\n\n return (\n <Tooltip title={props.rating.name} spanHack>\n {button}\n </Tooltip>\n );\n}\n\ninterface RatingRangeSelectorProps {\n ratings: Rating[];\n yearGroup?: YearGroup;\n yearGroups?: YearGroup[];\n selections: Rating[];\n onSelectRange: (range: Rating[]) => void;\n getButtonClasses: (rating: Rating, isActive: boolean, isHovering: boolean) => string;\n isDisabled?: (rating: Rating) => boolean;\n disabled?: boolean;\n}\n\nRatingRangeSelector.defaultProps = {\n selections: []\n};\n\nexport function RatingRangeSelector(props: RatingRangeSelectorProps): JSX.Element {\n const [ hoverRange, setHoverRange ] = React.useState<Rating[]>([]);\n\n function getRange(rating: Rating): Rating[] {\n return props.ratings.filter(r => r.code && r.value <= rating.value);\n }\n\n function onClickRating(rating: Rating): void {\n props.onSelectRange(getRange(rating));\n }\n\n function onHover(rating: Rating): void {\n if (!rating || props.isDisabled(rating)) {\n setHoverRange([]);\n return;\n }\n }\n\n function isActive(rating: Rating): boolean {\n if (hoverRange.length)\n return !!hoverRange.find(r => r.id === rating.id);\n\n return !!props.selections.find(r => r.id === rating.id);\n }\n\n return (\n <div>\n <ButtonGroup as='ul' className='list-unstyled mb-0'>\n {props.ratings.map(rating => (\n <li key={rating.id}>\n <RatingButton\n rating={rating}\n onClick={() => onClickRating(rating)}\n onHover={onHover}\n isActive={isActive(rating)}\n disabled={props.disabled || props.isDisabled?.(rating)}\n getButtonClasses={props.getButtonClasses}\n />\n </li>\n ))}\n </ButtonGroup>\n </div>\n );\n}\n",":local {\n .firstButton {\n border-radius: 0;\n border-top-left-radius: $border-radius;\n border-bottom-left-radius: $border-radius;\n }\n\n .lastButton {\n border-radius: 0;\n border-top-right-radius: $border-radius;\n border-bottom-right-radius: $border-radius;\n }\n}\n","import * as React from 'react';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { RatingRangeSelector } from 'libs/shared/components/rating-range-selector/RatingRangeSelector';\nimport { Rating } from 'libs/shared/interfaces';\n\nimport styles from './rating-filter.module.scss';\n\ntype OptionType = FilterOption & Rating;\n\nexport function RatingFilter(props: FilterProps): JSX.Element {\n const options = props.filter.options as OptionType[];\n\n function onSelectRange(range: OptionType[]): void {\n props.setDraftState({\n active: !!range.length,\n selection: range as FilterOption[]\n });\n }\n\n const filteredRatings: Rating[] = options.filter(r => r.code);\n const [firstRating] = filteredRatings;\n const lastRating = filteredRatings[filteredRatings.length - 1];\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n <p>{props.filter.description}</p>\n\n <div className='mb-2'>\n <RatingRangeSelector\n ratings={options}\n selections={props.draftState.selection as Rating[]}\n onSelectRange={onSelectRange}\n disabled={props.filter.disabled}\n isDisabled={(rating: Rating & FilterOption) => rating.disabled}\n getButtonClasses={(rating, isActive, isHovering) => {\n let className = 'btn border text-nowrap';\n\n if (isActive || isHovering)\n className += ' btn-dark';\n else\n className += ' btn-outline-dark';\n\n if (isHovering)\n className += ' active';\n\n if (filteredRatings.length === 1)\n className += ' rounded';\n else if (firstRating.id === rating.id)\n className += ' ' + styles.firstButton;\n else if (lastRating.id === rating.id)\n className += ' ' + styles.lastButton;\n else\n className += ' rounded-0';\n\n return className;\n }}\n />\n </div>\n </>\n );\n}\n","export const FilterConstants = {\n FILTER_PARAM_PREFIX: 'filters.',\n MAX_CHECKBOXES_PER_COLUMN: 10\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { FilterConstants } from 'libs/shared/apps/search/constants/FilterConstants';\nimport { FilterOption, SourceFilterOptions } from 'libs/shared/apps/search/interfaces';\nimport { MasterObjectTypes } from 'libs/shared/enums/MasterObjectTypes';\nimport { Library } from 'libs/shared/interfaces';\n\nconst namespace = 'sharedSearch.utils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst LIBRARY_FILTER = `${FilterConstants.FILTER_PARAM_PREFIX}library`;\n\nfunction getTypeMap(libraries: Library[]): HashObject {\n return libraries.reduce<HashObject>((prev, next) => {\n return {\n ...prev,\n [next.type]: true\n };\n }, {});\n}\n\nexport const SourceFilterHelper = {\n getOptions(opts: {\n libraries: Library[],\n isLearner: boolean,\n isGuest: boolean,\n hasCustomLibraries: boolean,\n liveStreams?: boolean\n }): FilterOption<SourceFilterOptions>[] {\n const { libraries, isLearner, isGuest, hasCustomLibraries, liveStreams } = opts;\n\n const options: FilterOption<SourceFilterOptions>[] = [];\n\n const libraryTypes = getTypeMap(libraries);\n\n if (libraryTypes[MasterObjectTypes.Workspace] && !isGuest)\n options.push({ id: SourceFilterOptions.MyVideos, name: getPhrase('myVideos') });\n\n if (libraryTypes[MasterObjectTypes.CustomLibrary] && (!isLearner || hasCustomLibraries))\n options.push({ id: SourceFilterOptions.School, name: getPhrase('schoolVideos') });\n\n if (libraryTypes[MasterObjectTypes.Exchange])\n options.push({ id: SourceFilterOptions.ExchangeArchive, name: getPhrase('exchangeArchiveVideos') });\n\n if (libraryTypes[MasterObjectTypes.HostedLibrary])\n options.push({ id: SourceFilterOptions.ClickView, name: getPhrase('clickViewVideos') });\n\n if (libraryTypes[MasterObjectTypes.HostedLibrary] && liveStreams)\n options.push({ id: SourceFilterOptions.LiveStreams, name: getPhrase('livestreams') });\n\n return options;\n },\n\n getBackendParamValue(\n val: SourceFilterOptions | SourceFilterOptions[],\n libraries: Library[],\n streamableLibraryId: string\n ): HashObject {\n const values = Array.isArray(val) ? val : [val];\n\n return values.reduce((acc, value) => {\n return libraries.reduce((prev, next) => {\n const libraryIds = prev[LIBRARY_FILTER] || [];\n\n if (value === SourceFilterOptions.MyVideos && next.type === MasterObjectTypes.Workspace)\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n \n if (value === SourceFilterOptions.School && next.type === MasterObjectTypes.CustomLibrary)\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n\n if (value === SourceFilterOptions.ExchangeArchive && next.type === MasterObjectTypes.Exchange)\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n \n if (\n value === SourceFilterOptions.ClickView &&\n next.type === MasterObjectTypes.HostedLibrary &&\n next.id.toString() !== streamableLibraryId\n )\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n\n if (value === SourceFilterOptions.LiveStreams &&\n next.type === MasterObjectTypes.HostedLibrary &&\n next.id.toString() === streamableLibraryId\n )\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n \n return prev;\n }, acc);\n }, {} as HashObject);\n }\n};\n","export enum CurationTag {\n CLICKVIEW_CURATED = 'is_clickview_curated',\n MOVIES_AND_TV = 'is_movies_and_tv',\n STREAMABLE_CURATED = 'is_streamable_learning_curated'\n}\n","export enum CustomerStatus {\n Unclassified = 0,\n Active = 1,\n Prospect = 2,\n LostCustomer = 3,\n Disabled = 4,\n Other = 5\n}\n\nexport enum CustomerStatusString {\n Unclassified = 'Unclassified',\n Active = 'Active',\n Prospect = 'Prospect',\n LostCustomer = 'LostCustomer',\n Disabled = 'Disabled',\n Other = 'Other'\n}\n","import { SpecialEventType } from 'libs/shared/interfaces';\n\nexport const SpecialEventTypeLabelMap: Record<SpecialEventType, string> = {\n [SpecialEventType.BreakingNews]: 'Breaking news',\n [SpecialEventType.HistoricalEvent]: 'Historical event',\n [SpecialEventType.Holiday]: 'Holiday',\n [SpecialEventType.Informal]: 'Informal',\n [SpecialEventType.Livestream]: 'Livestream',\n [SpecialEventType.NaturalDisaster]: 'Natural disaster',\n [SpecialEventType.Observance]: 'Observance',\n [SpecialEventType.ReligiousEvent]: 'Religious event',\n [SpecialEventType.SportingEvent]: 'Sporting event',\n \n [SpecialEventType.Other]: 'Other'\n};\n","import React from 'react';\n\nexport function WizardActionInfoContainer(props: React.PropsWithChildren<any>): JSX.Element {\n return (\n <div className='alert text-dark bg-light-blue px-2 rounded-3'>\n {props.children}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\n\nconst namespace = 'userManager.bulkUserActivationActionInfo';\n\ninterface BulkUserActivationActionInfoProps {\n userType: UserGroup;\n}\n\nexport function BulkUserActivationActionInfo(props: BulkUserActivationActionInfoProps): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='deactivate' /></h4>\n <p>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'deactivateInfoStudent' : 'deactivateInfoStaff'} />\n </p>\n\n <h4 className='h5'><Text namespace={namespace} phrase='reactivate' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'reactivateInfoStudent' : 'reactivateInfoStaff'} />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkUserActivationEmailActionInfo';\n\nexport function BulkUserActivationEmailActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.addToClassroomActionInfo';\n\nexport function BulkAddToClassroomActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.changeYearGroupActionInfo';\n\nexport function BulkChangeYearGroupActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\n\nconst namespace = 'userManager.bulkUserDeleteActionInfo';\n\ninterface BulkUserDeleteActionInfoProps {\n userType: UserGroup;\n}\n\nexport function BulkUserDeleteActionInfo(props: BulkUserDeleteActionInfoProps): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='delete' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'infoStudent' : 'infoStaff'} />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\n\nconst namespace = 'userManager.bulkUserRemoveActionInfo';\n\ninterface BulkUserRemoveActionInfoProps {\n userType: UserGroup;\n}\n\nexport function BulkUserRemoveActionInfo(props: BulkUserRemoveActionInfoProps): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='remove' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'infoStudent' : 'infoStaff'} />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkUserResetEmailActionInfo';\n\nexport function BulkUserResetEmailActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkResetPasswordActionInfo';\n\nexport function BulkResetPasswordActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkUserYearGroupRolloverActionInfo';\n\nexport function BulkUserYearGroupRolloverActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nexport function CheckCircleSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M12 3c4.972 0 9 4.028 9 9s-4.028 9-9 9-9-4.028-9-9 4.028-9 9-9m4.244 5.578a.77.77 0 0 0-1.058.068l-4.722 5.18-1.684-1.615a.77.77 0 0 0-1.06 0 .7.7 0 0 0 0 1.018l2.25 2.16a.77.77 0 0 0 1.094-.035l5.25-5.76a.7.7 0 0 0-.07-1.016'\n />\n </svg>\n );\n}\n",":local {\n .badge {\n border-radius: 3px;\n font-size: 0.8rem;\n\n &.pending {\n background-color: $gray-700;\n }\n\n &.active {\n background-color: $green-500;\n }\n }\n\n .name {\n max-width: 75%;\n }\n\n .username {\n max-width: 70%;\n }\n\n .lastActiveContainer {\n width: 5rem;\n\n &.isCurrentUser {\n width: 6.8rem; // Current user won't have the \"more action\" dropdown, so this needs to be slightly wider.\n }\n }\n\n .pillContainer {\n width: 6.25rem;\n }\n\n .avatarContainer {\n width: $cv-user-options-avatar-size;\n min-width: $cv-user-options-avatar-size;\n height: $cv-user-options-avatar-size;\n }\n\n .verifiedEmail {\n margin-right: 0.1rem;\n }\n\n .authMethodContainer {\n width: 6rem;\n }\n\n .authMethodLogo {\n @extend .avatarContainer;\n\n background-size: contain;\n margin-right: -10%;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { ObjectStatus } from 'libs/shared/enums/ObjectStatus';\nimport { CurrentUser, User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './user-item-components.module.scss';\n\nconst namespace = 'userManager.userList';\n\ninterface UserStatusBadgeProps {\n user?: Partial<User>;\n status?: ObjectStatus;\n currentUser?: CurrentUser;\n className?: string;\n showActiveBadge?: boolean;\n}\n\nexport function UserStatusBadge(props: UserStatusBadgeProps): JSX.Element {\n return (\n <>\n {/* \"Deactivated\" badge */}\n {(UserHelper.getUserStatusFromValue(props.user?.status ?? props.status) === ObjectStatus.Disabled) && (\n <div className={`text-white px-1 ${styles.badge} bg-danger ${props.className ?? ''}`}>\n <Text namespace={namespace} phrase='deactivated' />\n </div>\n )}\n\n {/* \"Pending badge\" */}\n {(UserHelper.getUserStatusFromValue(props.user?.status ?? props.status) === ObjectStatus.Inactive) && (\n <div className={`text-white px-1 ${styles.badge} ${styles.pending} ${props.className ?? ''}`}>\n <Tooltip title={LanguageService.getPhrase(namespace, 'pendingTooltip')} spanHack>\n <Text namespace={namespace} phrase='pending' />\n </Tooltip>\n </div>\n )}\n\n {/* \"Active badge\" */}\n {props.showActiveBadge &&\n (UserHelper.getUserStatusFromValue(props.user?.status ?? props.status) === ObjectStatus.Active)\n && (\n <div className={`text-white px-1 ${styles.badge} ${styles.active} ${props.className ?? ''}`}>\n <Tooltip title={LanguageService.getPhrase(namespace, 'active')} spanHack>\n <Text namespace={namespace} phrase='active' />\n </Tooltip>\n </div>\n )}\n\n {/* \"That's me\" badge */}\n {props.user?.id.toString() === props.currentUser?.id.toString() && (\n <div className={`text-white px-1 ${styles.badge} bg-blue ${props.className ?? ''}`}>\n <Text namespace={namespace} phrase='thatsYou' />\n </div>\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\nimport { CurrentUser, User } from 'libs/shared/interfaces';\n\nimport { UserStatusBadge } from './UserStatusBadge';\n\nimport styles from './user-item-components.module.scss';\n\nconst namespace = 'userManager.userList';\n\ninterface BasicUserDetailsProps {\n user: Partial<User>;\n currentUser?: CurrentUser;\n wrapperClassName?: string;\n}\n\nexport function BasicUserDetails(props: BasicUserDetailsProps): JSX.Element {\n const { user, currentUser } = props;\n\n return (\n <div className={`d-flex flex-column justify-content-center me-auto w-100 ${props.wrapperClassName}`}>\n <div className='pb-1 d-flex align-items-center'>\n {/* Name, username, and status */}\n <div className={`d-flex ${styles.name}`}>\n {user.name ? (\n <h2\n className='h5 m-0 me-1 d-inline-block align-middle text-truncate'\n title={`${user.name} ${user.surname || ''}`}\n >\n {user.name} {user.surname || ''}\n </h2>\n ) : (\n <span className='fst-italic text-secondary me-2'>\n <Text namespace={namespace} phrase='noName' />\n </span>\n )}\n {user.username && (\n <>\n (\n <p title={user.username} className={`m-0 d-inline-block align-middle text-truncate ${styles.username}`}>\n {user.username}\n </p>\n )\n </>\n )}\n </div>\n\n <UserStatusBadge user={user} currentUser={currentUser} className='ms-2' />\n </div>\n\n {/* Email and verification status */}\n <div className='d-flex'>\n {!!user.metadata?.isEmailVerified && (\n <SvgContainer\n className={`svg-container text-secondary ms-n1 ${styles.verifiedEmail}`}\n svg={CheckCircleSvg}\n title={LanguageService.getPhrase(namespace, 'emailVerified')}\n tooltipSpanHack\n tooltipPlacement='top'\n />\n )}\n <p className='text-truncate mb-0 overflow-visible'>\n {user.email ?\n user.email :\n (\n <span className='fst-italic'>\n <Text namespace={namespace} phrase='noEmail' />\n </span>\n )\n }\n </p>\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { User } from 'libs/shared/interfaces';\n\nconst namespace = 'userManager.userList';\n\ninterface RoleOrYearGroupProps {\n userType: UserGroup;\n user?: Partial<User>;\n countryCode?: string;\n badgeText?: string;\n}\n\nfunction getBadgeText(props: RoleOrYearGroupProps): string {\n if (props.userType === UserGroup.Learner) {\n if (props.user?.masterYearGroup?.name)\n return props.user?.masterYearGroup.name;\n\n if (props.user?.yearGroups?.data?.length)\n return ArrayHelper.first(props.user?.yearGroups.data).name;\n\n return null;\n }\n\n if (props.userType === UserGroup.Staff) {\n if (props.user?.userProfile?.role === UserRole.Admin)\n return LanguageService.getPhrase(namespace, 'admin');\n \n if (props.user?.userProfile?.role === UserRole.SuperAdmin)\n return LanguageService.getPhrase(namespace, props.countryCode === 'US' ? 'superAdminUs' : 'superAdmin');\n\n return null;\n }\n}\n\nexport function RoleOrYearGroup(props: RoleOrYearGroupProps): JSX.Element {\n const badgeText = props.badgeText || getBadgeText(props);\n\n if (!badgeText)\n return <></>;\n\n return (\n <div className='rounded-pill border border-dark bg-white px-2 me-3 d-inline-block flex-shrink-0'>\n {badgeText}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './user-item-components.module.scss';\n\ninterface UserItemAvatarProps {\n user: Partial<User>;\n imageCdnUrl: string;\n}\n\nexport function UserItemAvatar(props: UserItemAvatarProps): JSX.Element {\n return (\n <div className={`${styles.avatarContainer} mx-2`}>\n <Avatar\n imageUrl={props.user.avatar?.url}\n imageCdnUrl={props.imageCdnUrl}\n initials={UserHelper.getInitials(props.user.name, props.user.surname)}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { BaseUserItemProps } from 'libs/shared/apps/user-manager/components/user-list/UserList';\nimport { BasicUserDetails } from 'libs/shared/apps/user-manager/components/user-list-items/components/BasicUserDetails';\nimport { RoleOrYearGroup } from 'libs/shared/apps/user-manager/components/user-list-items/components/RoleOrYearGroup';\nimport { UserItemAvatar } from 'libs/shared/apps/user-manager/components/user-list-items/components/UserItemAvatar';\nimport { CurrentUser } from 'libs/shared/interfaces';\n\ninterface BulkUserActionsErroredUserItemProps extends BaseUserItemProps {\n imageCdnUrl: string;\n errorMessage: string;\n currentUser?: CurrentUser;\n}\n\nexport function BulkUserActionsErroredUserItem(props: BulkUserActionsErroredUserItemProps): JSX.Element {\n return (\n <li className='d-flex align-items-center p-2'>\n <UserItemAvatar user={props.user} imageCdnUrl={props.imageCdnUrl} />\n\n <BasicUserDetails user={props.user} currentUser={props.currentUser} />\n\n <RoleOrYearGroup userType={props.userType} user={props.user} />\n\n <p className='mb-0 mx-2 text-danger'>\n {props.errorMessage}\n </p>\n </li>\n );\n}\n","export enum UserManagerClient {\n Online = 'online',\n Primary = 'primary',\n Curator = 'curator'\n}\n","import React from 'react';\n\ntype WizardContext = {\n disableNext?: boolean,\n setDisableNext?: (val: boolean) => void,\n\n onClickConfirm?: () => void,\n setOnClickConfirm?: (cb: () => void) => void,\n\n showButtons?: boolean,\n setShowButtons?: (val: boolean) => void,\n\n showSpinner?: boolean,\n setShowSpinner?: (val: boolean) => void\n};\n\nexport const WizardLayoutContext = React.createContext<WizardContext>({});\n\nexport const WizardLayoutContextProvider = (props: React.PropsWithChildren<any>) => {\n const [ disableNext, setDisableNext ] = React.useState(false);\n const [ onClickConfirm, setOnClickConfirm ] = React.useState(null);\n const [ showButtons, setShowButtons ] = React.useState(true);\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n\n return (\n <WizardLayoutContext.Provider value={{\n disableNext,\n setDisableNext,\n onClickConfirm,\n setOnClickConfirm,\n showButtons,\n setShowButtons,\n showSpinner,\n setShowSpinner\n }}>\n {props.children}\n </WizardLayoutContext.Provider>\n );\n};\n","export enum BatchDataType {\n Unknown = 0,\n Staff = 1,\n Learner = 2,\n MasterVideo = 3,\n Rostering = 8,\n MarketingProfile = 16\n}\n","export enum BatchJobName {\n YearGroupRollover = 'year-group-rollover',\n ChangeYearGroup = 'change-year-group',\n DeleteUser = 'delete-user',\n RemoveUser = 'remove-user',\n DeactivateUser = 'deactivate-user',\n ActivateUser = 'activate-user',\n AddToClassroom = 'add-to-classroom',\n ResetPassword = 'reset-password',\n SendResetPasswordEmail = 'send-reset-password-email',\n SendAccountActivationEmail = 'send-account-activation-email',\n CreateUser = 'create-user',\n\n AddToAudience = 'add-to-audience',\n AddToBackboneClassification = 'add-to-backbone-classification',\n AddToBackboneAudience = 'add-to-backbone-audience',\n AddToClassification = 'add-to-classification',\n AddToSeries = 'add-to-series',\n AddToDirector = 'add-to-director',\n AddToDistributor = 'add-to-distributor',\n AddToProductionCompany = 'add-to-production-company',\n AddToProducer = 'add-to-producer',\n SetProductionYear = 'set-production-year',\n AddToLibrary = 'add-to-library',\n AddToCurationTag = 'add-to-curation-tag',\n AddToSkillTag = 'add-to-skill-tag',\n AddToPedagogyTag = 'add-to-pedagogy-tag',\n AddToNormalTag = 'add-to-normal-tag',\n AddToHiddenTag = 'add-to-hidden-tag',\n AddResourceAndLink = 'add-resource-and-link',\n\n Rostering = 'rostering',\n MarketingProfile = 'marketing-profile',\n UpdateProspectDomains = 'update-prospect-domains',\n AddAliases = 'add-aliases',\n AddPartnerProfiles = 'add-partner-profiles'\n}\n","export enum BatchJobResultErrorCode {\n NoAction = 1,\n // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n Succeed = 1,\n Unknown = 10,\n\n CustomerNotFound = 100,\n UserNotFound = 101,\n\n EmailNotVerified = 131,\n UserDisabled = 133,\n\n InvalidYearGroup = 200,\n MissingYearGroup = 201,\n NewYearGroupNotSet = 202,\n\n ObjectNotFoundInBackboneClassification = 300,\n ObjectNotFoundInBackboneAudience = 301\n}\n","export enum BatchJobType {\n RolloverYearGroup = 1,\n DeactivateUser = 2,\n ChangeYearGroup = 3,\n DeleteUser = 4,\n CreateUser = 5,\n ResetPassword = 6,\n AddUsersClassroom = 7,\n SendAccountReminderEmail = 8,\n ActivateUser = 9,\n AddToBackboneClassification = 10,\n AddToClassification = 11,\n AddToBackboneAudience = 12,\n AddToAudience = 13,\n AddVideosSeries = 14,\n AddVideosDistributor = 15,\n AddVideosProductionCompany = 16,\n AddVideosProducer = 17,\n AddVideosDirector = 18,\n AddVideosLibrary = 19,\n AddVideosResourceAndLinks = 21,\n AddVideosTag = 22,\n SendAccountActivationEmail = 23,\n RemoveUser = 24,\n Rostering = 25,\n MarketingProfile = 26,\n SetProductionYear = 28,\n UpdateProspectDomains = 29,\n AddAliases = 30,\n AddPartnerProfiles = 31\n}\n","import React from 'react';\n\nexport function KeySvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M12.335 4C14.7258 4.00011 16.6631 5.90392 16.6631 8.26074C16.6629 9.95954 15.6586 11.3904 13.877 12.2334L15.2314 13.5742C15.4776 13.8297 15.4899 14.2192 15.2373 14.4619L13.7734 15.8994L14.7773 16.8828C15.0235 17.1318 15.0366 17.5149 14.7842 17.7705L12.7822 19.7441C12.523 19.9933 12.153 19.9618 11.8809 19.7383L10.8252 18.8252C10.6373 18.6591 10.5723 18.4158 10.5723 18.2051V12.1758C8.99791 11.4924 8.00018 9.97233 8 8.26074C8 5.89108 9.9246 4 12.335 4ZM12.335 5.02832C10.5078 5.02832 9.03711 6.47232 9.03711 8.26074C9.03732 9.79975 10.0929 11.096 11.6152 11.4346V18.0264L12.335 18.7285L13.7471 17.3174L12.8271 16.4229V15.3633L14.2012 14.0283L12.9307 12.7695V11.4795C14.5568 11.0963 15.6199 9.78709 15.6201 8.26074C15.6201 6.47238 14.1556 5.02843 12.335 5.02832ZM12.3496 5.875C13.125 5.875 13.7559 6.50584 13.7559 7.28125C13.7559 8.05666 13.125 8.6875 12.3496 8.6875C11.5744 8.68728 10.9434 8.05652 10.9434 7.28125C10.9434 6.50598 11.5744 5.87522 12.3496 5.875ZM12.3496 6.8125C12.0913 6.81272 11.8809 7.02291 11.8809 7.28125C11.8809 7.53959 12.0913 7.74978 12.3496 7.75C12.6081 7.75 12.8184 7.53972 12.8184 7.28125C12.8184 7.02278 12.6081 6.8125 12.3496 6.8125Z'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nimport { DevError } from 'libs/common/backbone/errors/DevError';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { FilterOption } from 'libs/shared/apps/search/interfaces';\nimport { BulkUserActionOptions, BulkUserActionStepId, BulkUserSubAction } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/layout/BulkUserActionsWizardLayout';\nimport { BulkUserActivationActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/activation-action-info/BulkUserActivationActionInfo';\nimport { BulkUserActivationEmailActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/activation-email-info/BulkUserActivationEmailActionInfo';\nimport { BulkAddToClassroomActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/add-to-classroom-action-info/BulkAddToClassroomActionInfo';\nimport { BulkChangeYearGroupActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/change-year-group-action-info/ChangeYearGroupActionInfo';\nimport { BulkUserDeleteActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/delete-action-info/BulkUserDeleteActionInfo';\nimport { BulkUserRemoveActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/remove-action-info/BulkUserRemoveActionInfo';\nimport { BulkUserResetEmailActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/reset-email-info/BulkUserResetEmailActionInfo';\nimport { BulkResetPasswordActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/reset-password-action-info/BulkResetPasswordActionInfo';\nimport { BulkUserYearGroupRolloverActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/year-group-rollover-action-info/BulkUserYearGroupRolloverActionInfo';\nimport { BulkUserActionsErroredUserItem } from 'libs/shared/apps/user-manager/components/user-list-items/bulk-user-actions-errored-user-item/BulkUserActionsErroredUserItem';\nimport { UserManagerClient } from 'libs/shared/apps/user-manager/enums/UserManagerClient';\nimport { AllowYearGroupRollover } from 'libs/shared/apps/user-manager/hooks/useAllowAnnualYearGroupRollover';\nimport { UserManagerAppLinks } from 'libs/shared/apps/user-manager/interfaces';\nimport { UserManagerQueryParams } from 'libs/shared/apps/user-manager/interfaces/query-params/UserManagerQueryParams';\nimport { BulkUserActionsAddToClassroomViewModel, BulkUserActionsResetPasswordViewModel, BulkUserActionsViewModel, BulkUserActionsYearGroupRolloverViewModel } from 'libs/shared/apps/user-manager/interfaces/viewmodels/BulkUserActionsViewModel';\nimport { WizardOptionHash } from 'libs/shared/components/wizard/options/WizardOptions';\nimport { ObjectWithErrorCode } from 'libs/shared/components/wizard/status/statuses/completed-with-error/WizardCompletedWithError';\nimport { WizardStep } from 'libs/shared/components/wizard/step-list/WizardStepList';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { WizardLayoutContext } from 'libs/shared/context/WizardLayoutContext';\nimport { BatchDataType } from 'libs/shared/enums/BatchDataType';\nimport { BatchJobName } from 'libs/shared/enums/BatchJobName';\nimport { BatchJobResultErrorCode } from 'libs/shared/enums/BatchJobResultErrorCode';\nimport { BatchJobType } from 'libs/shared/enums/BatchJobType';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { DeleteSvg } from 'libs/shared/images/svg/actions/DeleteSvg';\nimport { ClassroomsSvg } from 'libs/shared/images/svg/objects/ClassroomsSvg';\nimport { EmailSvg } from 'libs/shared/images/svg/objects/EmailSvg';\nimport { FolderSvg } from 'libs/shared/images/svg/objects/FolderSvg';\nimport { GraduationCapSvg } from 'libs/shared/images/svg/objects/GraduationCapSvg';\nimport { GroupSvg } from 'libs/shared/images/svg/objects/GroupSvg';\nimport { KeySvg } from 'libs/shared/images/svg/objects/KeySvg';\nimport { AddToClassroomJobMetadata, BaseBatchJobMetadata, BatchJobMetadata, ChangeYearGroupJobMetadata, CreateBatchJobRequest, CurrentUser, ResetPasswordJobMetadata, User, WizardActionVerb, YearGroup, YearGroupRolloverJobMetadata } from 'libs/shared/interfaces';\nimport { CountsByStatus } from 'libs/shared/interfaces/models/SearchAggregation';\n\nconst getPhrase = LanguageService.encloseNamespace('userManager.utils');\n\nexport const SUPPORTED_BATCH_JOB_TYPES = [\n BatchJobType.ActivateUser,\n BatchJobType.AddUsersClassroom,\n BatchJobType.ChangeYearGroup,\n BatchJobType.DeactivateUser,\n BatchJobType.DeleteUser,\n BatchJobType.ResetPassword,\n BatchJobType.RolloverYearGroup,\n BatchJobType.SendAccountReminderEmail,\n BatchJobType.CreateUser,\n BatchJobType.SendAccountActivationEmail,\n BatchJobType.RemoveUser\n];\n\nexport const BulkUserActionsHelper = {\n getSteps(\n userType: UserGroup,\n userCount: number,\n appLinks?: UserManagerAppLinks,\n action?: BulkUserActionOptions\n ): WizardStep<BulkUserActionStepId>[] {\n const actions: WizardStep<BulkUserActionStepId>[] = [\n {\n id: 'select-action',\n text: getPhrase('choose'),\n appLink: appLinks?.bulkActionsSelectAction\n },\n {\n id: 'action-details',\n text: getPhrase('details'),\n appLink: appLinks?.bulkActionsActionDetails?.[action],\n disabled: !appLinks?.bulkActionsActionDetails?.[action]\n },\n {\n id: 'confirmation',\n text: getPhrase('confirmation')\n },\n {\n id: 'status',\n text: getPhrase('status')\n }\n ];\n\n const reviewAccountsAction: WizardStep<BulkUserActionStepId> = {\n id: 'review-accounts',\n text: getPhrase(userType === UserGroup.Learner ? 'reviewStudents' : 'reviewStaff'),\n subText: getPhrase(userType === UserGroup.Learner ? 'reviewSubTextStudents' : 'reviewSubTextStaff', { smartCount: userCount }),\n appLink: appLinks?.bulkActionsReviewAccounts\n };\n\n if (typeof (userCount) !== 'number')\n delete reviewAccountsAction.subText;\n\n actions.unshift(reviewAccountsAction);\n\n return actions;\n },\n\n getActionOptions({\n userType,\n allowYearGroupRollover,\n countsByStatus,\n client,\n products,\n yearGroups,\n hasClassroomsFeature\n }: {\n userType: UserGroup,\n allowYearGroupRollover: AllowYearGroupRollover,\n countsByStatus: CountsByStatus,\n client: UserManagerClient,\n products?: ProductId[],\n yearGroups?: YearGroup[],\n hasClassroomsFeature: boolean\n }): WizardOptionHash<BulkUserActionOptions>[] {\n const actions: WizardOptionHash<BulkUserActionOptions>[] = [];\n\n actions.push({\n order: 40,\n id: 'activation',\n icon: FolderSvg,\n name: getPhrase('deactivateReactivate'),\n infoComponent: () => <BulkUserActivationActionInfo userType={userType} />\n });\n\n const disableDeleteAction = !countsByStatus?.Disabled && !countsByStatus?.Inactive;\n\n const showDelete = client !== UserManagerClient.Primary || products?.includes(ProductId.Online);\n if (showDelete) {\n actions.push({\n order: 50,\n id: 'delete',\n icon: DeleteSvg,\n name: getPhrase('delete'),\n infoComponent: () => <BulkUserDeleteActionInfo userType={userType} />,\n disabled: disableDeleteAction,\n tooltip: disableDeleteAction ? getPhrase('deleteDisabledTooltip') : ''\n });\n }\n const showRemove = client !== UserManagerClient.Online && !products?.includes(ProductId.Online);\n\n if (showRemove) {\n actions.push({\n order: 50,\n id: 'removeFromSchool',\n icon: DeleteSvg,\n name: getPhrase('removeFromSchool'),\n infoComponent: () => <BulkUserRemoveActionInfo userType={userType} />,\n disabled: disableDeleteAction,\n tooltip: disableDeleteAction ? getPhrase('removeFromSchoolDisabledTooltip') : ''\n });\n }\n\n if (userType === UserGroup.Learner) {\n if (yearGroups?.length > 1) {\n actions.push({\n order: 20,\n id: 'changeYearGroup',\n icon: GroupSvg,\n name: getPhrase('changeYearGroup'),\n infoComponent: () => <BulkChangeYearGroupActionInfo />\n });\n }\n \n actions.push({\n order: 30,\n id: 'resetPassword',\n icon: KeySvg,\n name: getPhrase('resetPassword'),\n // TODO: Replace all of these info components with a shared component that accepts a heading and message prop\n infoComponent: () => <BulkResetPasswordActionInfo />\n });\n\n actions.push({\n order: 35,\n id: 'activationEmail',\n icon: EmailSvg,\n name: getPhrase('activationEmail'),\n infoComponent: () => <BulkUserActivationEmailActionInfo />\n });\n\n if (hasClassroomsFeature) {\n actions.push({\n order: 60,\n id: 'addToClassroom',\n icon: ClassroomsSvg,\n name: getPhrase('addToClassroom'),\n infoComponent: () => <BulkAddToClassroomActionInfo />\n });\n }\n \n if (yearGroups?.length > 1) {\n actions.push({\n order: 70,\n id: 'yearGroupRollover',\n icon: GraduationCapSvg,\n name: getPhrase('yearGroupRollover'),\n infoComponent: () => <BulkUserYearGroupRolloverActionInfo />,\n disabled: !allowYearGroupRollover?.canRollover,\n tooltip: getYearGroupRolloverDisabledTooltip(allowYearGroupRollover)\n });\n }\n }\n\n if (userType === UserGroup.Staff) {\n actions.push({\n order: 60,\n id: 'resetEmail',\n icon: EmailSvg,\n name: getPhrase('resetEmail'),\n infoComponent: () => <BulkUserResetEmailActionInfo />\n });\n }\n\n return actions.sort((a, b) => a.order - b.order);\n },\n\n mapSubActionToDisplayName(subAction: BulkUserSubAction): string {\n switch (subAction) {\n case 'yearGroupRollover':\n return getPhrase('yearGroupRolloverDisplayName');\n case 'changeYearGroup':\n return getPhrase('changeYearGroupDisplayName');\n case 'deactivate':\n return getPhrase('deactivateDisplayName');\n case 'reactivate':\n return getPhrase('reactivateDisplayName');\n case 'delete':\n return getPhrase('deleteDisplayName');\n case 'addToClassroom':\n return getPhrase('addToClassroomDisplayName');\n case 'resetPassword':\n return getPhrase('resetPasswordDisplayName');\n case 'resetEmail':\n return getPhrase('resetEmailDisplayName');\n case 'activationEmail':\n return getPhrase('activationEmailDisplayName');\n case 'removeFromSchool':\n return getPhrase('removeFromSchoolDisplayName');\n default:\n return '';\n }\n },\n\n getWizardAppLinks(appLinks: UserManagerAppLinks): Core.AppLink[] {\n const actionDetailsActions = Object.keys(appLinks.bulkActionsActionDetails)\n .map((key: keyof typeof appLinks.bulkActionsActionDetails) => {\n return appLinks.bulkActionsActionDetails[key];\n });\n\n const confirmationAppLinks = Object.keys(appLinks.bulkActionsConfirmation)\n .map((key: keyof typeof appLinks.bulkActionsConfirmation) => {\n return appLinks.bulkActionsConfirmation[key];\n });\n\n const statusAppLinks = Object.keys(appLinks.bulkActionsStatus)\n .map((key: keyof typeof appLinks.bulkActionsStatus) => {\n return appLinks.bulkActionsStatus[key];\n });\n\n return [\n appLinks.bulkActionsReviewAccounts,\n appLinks.bulkActionsSelectAction,\n ...actionDetailsActions,\n ...confirmationAppLinks,\n ...statusAppLinks\n ];\n },\n\n getErrorListItem(\n object: ObjectWithErrorCode<User>,\n imageCdnUrl: string,\n currentUser?: CurrentUser\n ): JSX.Element {\n const errorMessage = this.getUserErrorMessage(object.errorCode);\n return (\n <BulkUserActionsErroredUserItem\n user={object}\n userType={object.userType}\n imageCdnUrl={imageCdnUrl}\n errorMessage={errorMessage}\n currentUser={currentUser}\n />\n );\n },\n\n getUserErrorMessage(errorCode: BatchJobResultErrorCode): string {\n switch (errorCode) {\n case BatchJobResultErrorCode.NoAction:\n case BatchJobResultErrorCode.Succeed:\n return '';\n\n case BatchJobResultErrorCode.InvalidYearGroup:\n return getPhrase('invalidYearGroupError');\n case BatchJobResultErrorCode.MissingYearGroup:\n return getPhrase('missingYearGroupError');\n case BatchJobResultErrorCode.NewYearGroupNotSet:\n return getPhrase('yearGroupUpdateError');\n\n case BatchJobResultErrorCode.EmailNotVerified:\n return getPhrase('emailNotVerifiedError');\n\n case BatchJobResultErrorCode.UserDisabled:\n return getPhrase('userDeactivatedError');\n\n /**\n * I feel like by the this point, none of these errors should be getting thrown.\n * If they do get thrown, we use a generic error message and append the error code\n * in case it does happen and a screenshot is sent to support (hoping this helps).\n */\n case BatchJobResultErrorCode.Unknown:\n case BatchJobResultErrorCode.CustomerNotFound:\n case BatchJobResultErrorCode.UserNotFound:\n default:\n return getPhrase('genericUnexpectedError', { errorCode });\n }\n },\n\n getCreateJobRequestData(\n viewModel: BulkUserActionsViewModel,\n customerId: string,\n userType: UserGroup,\n currentUser?: CurrentUser\n ): CreateBatchJobRequest {\n switch (viewModel.subAction) {\n case 'yearGroupRollover': {\n return {\n name: BatchJobName.YearGroupRollover,\n type: BatchJobType.RolloverYearGroup,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getYearGroupRolloverJobMetadata(\n viewModel as BulkUserActionsYearGroupRolloverViewModel,\n customerId\n )\n };\n }\n\n case 'changeYearGroup': {\n return {\n name: BatchJobName.ChangeYearGroup,\n type: BatchJobType.ChangeYearGroup,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getChangeYearGroupJobMetadata(\n viewModel as BulkUserActionsYearGroupRolloverViewModel\n )\n };\n }\n\n case 'delete': {\n return {\n name: BatchJobName.DeleteUser,\n type: BatchJobType.DeleteUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'removeFromSchool': {\n return {\n name: BatchJobName.RemoveUser,\n type: BatchJobType.RemoveUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'deactivate': {\n return {\n name: BatchJobName.DeactivateUser,\n type: BatchJobType.DeactivateUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getDeactivateUsersJobMetadata(viewModel, currentUser)\n };\n }\n\n case 'reactivate': {\n return {\n name: BatchJobName.ActivateUser,\n type: BatchJobType.ActivateUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'addToClassroom': {\n return {\n name: BatchJobName.AddToClassroom,\n type: BatchJobType.AddUsersClassroom,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getAddToClassroomJobMetadata(\n viewModel as BulkUserActionsAddToClassroomViewModel\n )\n };\n }\n\n case 'resetPassword': {\n return {\n name: BatchJobName.ResetPassword,\n type: BatchJobType.ResetPassword,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getResetPasswordJobMetadata(viewModel as BulkUserActionsResetPasswordViewModel)\n };\n }\n\n case 'resetEmail': {\n return {\n name: BatchJobName.SendResetPasswordEmail,\n type: BatchJobType.SendAccountReminderEmail,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'activationEmail': {\n return {\n name: BatchJobName.SendAccountActivationEmail,\n type: BatchJobType.SendAccountActivationEmail,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n default:\n Core.ErrorHelper.throw(\n new DevError(`No handler for type ${viewModel.subAction} in BulkUserActionsHelper.getCreateJobRequestData`)\n );\n }\n\n return null;\n },\n\n useSetWizardConfirmationCallback(onClickConfirm: () => void): void {\n const { setOnClickConfirm } = React.useContext(WizardLayoutContext);\n const [viewModel] = useViewModel<BulkUserActionsViewModel>(SharedViewModelKeys.BULK_USER_ACTIONS);\n\n React.useEffect(() => {\n setOnClickConfirm(() => onClickConfirm);\n }, [viewModel?.subAction]);\n },\n\n useCreateJobErrorAlert(): () => void {\n const alerts = useAlerts();\n return () => {\n alerts.error(getPhrase('failedToCreateJob'));\n };\n },\n\n mapDataTypeToUserType(dataType: BatchDataType): UserGroup {\n switch (dataType) {\n case BatchDataType.Staff:\n return UserGroup.Staff;\n case BatchDataType.Learner:\n return UserGroup.Learner;\n default:\n return UserGroup.Unknown;\n }\n },\n\n mapUserTypeToDataType(userType: UserGroup): BatchDataType {\n switch (userType) {\n case UserGroup.Learner:\n return BatchDataType.Learner;\n case UserGroup.Staff:\n return BatchDataType.Staff;\n case UserGroup.Unknown:\n return BatchDataType.Unknown;\n }\n },\n\n getActionTypeFilterOptions(): FilterOption<BatchJobType>[] {\n return [{\n id: BatchJobType.ActivateUser,\n name: getPhrase('activate')\n }, {\n id: BatchJobType.DeactivateUser,\n name: getPhrase('deactivate')\n }, {\n id: BatchJobType.DeleteUser,\n name: getPhrase('deleteUser')\n }, {\n id: BatchJobType.RolloverYearGroup,\n name: getPhrase('yearGroupRollover')\n }, {\n id: BatchJobType.ChangeYearGroup,\n name: getPhrase('changeYearGroup')\n }, {\n id: BatchJobType.CreateUser,\n name: getPhrase('createUser')\n }, {\n id: BatchJobType.ResetPassword,\n name: getPhrase('resetPassword')\n }, {\n id: BatchJobType.SendAccountReminderEmail,\n name: getPhrase('resetEmail')\n }, {\n id: BatchJobType.AddUsersClassroom,\n name: getPhrase('addToClassroom')\n }, {\n id: BatchJobType.SendAccountActivationEmail,\n name: getPhrase('activationEmail')\n }, {\n id: BatchJobType.RemoveUser,\n name: getPhrase('removeFromSchool')\n }];\n },\n\n getUserTypeFilterOptions(): FilterOption<UserGroup>[] {\n return [{\n id: UserGroup.Staff,\n name: getPhrase('staff')\n }, {\n id: UserGroup.Learner,\n name: getPhrase('students')\n }];\n },\n\n mapSubActionToVerb(subAction: BulkUserSubAction): WizardActionVerb {\n if (subAction === 'delete')\n return 'Delete';\n\n if (subAction === 'removeFromSchool')\n return 'Remove';\n\n if (subAction === 'resetEmail' || subAction === 'activationEmail')\n return 'Email';\n\n if (subAction === 'addToClassroom')\n return 'Add';\n\n return 'Update';\n },\n\n mapJobTypeToName(type: BatchJobType): string {\n switch (type) {\n case BatchJobType.ActivateUser:\n return getPhrase('activate');\n case BatchJobType.AddUsersClassroom:\n return getPhrase('addToClassroom');\n case BatchJobType.ChangeYearGroup:\n return getPhrase('changeYearGroup');\n case BatchJobType.DeactivateUser:\n return getPhrase('deactivate');\n case BatchJobType.DeleteUser:\n return getPhrase('delete');\n case BatchJobType.ResetPassword:\n return getPhrase('resetPassword');\n case BatchJobType.RolloverYearGroup:\n return getPhrase('yearGroupRollover');\n case BatchJobType.SendAccountReminderEmail:\n return getPhrase('sendAccountReminderEmail');\n case BatchJobType.CreateUser:\n return getPhrase('bulkUpload');\n case BatchJobType.SendAccountActivationEmail:\n return getPhrase('sendAccountActivationEmail');\n case BatchJobType.RemoveUser:\n return getPhrase('removeUser');\n default:\n return getPhrase('unknown');\n }\n },\n\n hasFilterOrQuery(params: UserManagerQueryParams): boolean {\n return !!(params.query ||\n params.isAdmin ||\n params.status ||\n params.yearGroup);\n }\n};\n\nfunction setupBaseJobMetadata(\n viewModel: BulkUserActionsViewModel\n): BatchJobMetadata {\n return {\n batchObjectIds: [...viewModel.userIdMap.keys()],\n fullBatchObjects: undefined\n };\n}\n\nfunction getYearGroupRolloverJobMetadata(\n viewModel: BulkUserActionsYearGroupRolloverViewModel,\n customerId: string\n): YearGroupRolloverJobMetadata {\n // Year level rollover can only ever be run with all students\n return {\n fullBatchObjects: {\n source: 'UserApi',\n ownerId: customerId,\n objectType: MasterType.User,\n query: `{userType:${UserGroup.Learner}}`\n },\n finalYearGroupId: viewModel.yearGroup.id\n };\n}\n\nfunction getChangeYearGroupJobMetadata(\n viewModel: BulkUserActionsYearGroupRolloverViewModel\n): ChangeYearGroupJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as ChangeYearGroupJobMetadata;\n\n metadata.newYearGroupId = viewModel.yearGroup.id;\n\n return metadata;\n}\n\nfunction getResetPasswordJobMetadata(\n viewModel: BulkUserActionsResetPasswordViewModel\n): ResetPasswordJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as ResetPasswordJobMetadata;\n\n metadata.newPassword = viewModel.password;\n metadata.changeOnNextLogin = viewModel.changeOnNextLogin;\n\n return metadata;\n}\n\nfunction getYearGroupRolloverDisabledTooltip(status: AllowYearGroupRollover): string {\n if (status.canRollover)\n return '';\n\n switch (status.reason) {\n case 'select-all-students':\n return getPhrase('selectAllStudents');\n case 'cooldown':\n return getPhrase('rolloverCooldown', {\n date: DateHelper.format(status.lastRolloverDate, 'DD/MM/YYYY')\n });\n }\n}\n\nfunction getAddToClassroomJobMetadata(\n viewModel: BulkUserActionsAddToClassroomViewModel\n): AddToClassroomJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as AddToClassroomJobMetadata;\n\n metadata.classroomIds = [viewModel.classroom.id];\n\n return metadata;\n}\n\nfunction getDeactivateUsersJobMetadata(\n viewModel: BulkUserActionsViewModel,\n currentUser: CurrentUser\n): BatchJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as BaseBatchJobMetadata;\n\n if (!currentUser?.id)\n return metadata;\n\n metadata.batchObjectIds = metadata.batchObjectIds?.filter(id => {\n return id.toString() !== currentUser.id.toString();\n }) ?? [];\n\n return metadata;\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { DurationFilterOptions, FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nconst namespace = 'search.durationFilter';\n\nfunction mapOptionToDurationRange(option: FilterOption<DurationFilterOptions>): string {\n let phraseKey = '';\n\n switch (option.id) {\n case 'bite-sized':\n phraseKey = 'rangeBiteSized';\n break;\n\n case 'short':\n phraseKey = 'rangeShort';\n break;\n \n case 'medium':\n phraseKey = 'rangeMedium';\n break;\n\n case 'long':\n phraseKey = 'rangeLong';\n break;\n }\n \n return LanguageService.getPhrase(namespace, phraseKey);\n}\n\ninterface DurationOptionProps {\n onClick: (option: FilterOption<DurationFilterOptions>) => void;\n option: FilterOption<DurationFilterOptions>;\n active: boolean;\n disabled?: boolean;\n}\n\nfunction DurationOption(props: DurationOptionProps): JSX.Element {\n return (\n <li className='d-flex flex-fill flex-column align-items-center mb-2 mb-md-0 mx-1'>\n <button\n onClick={() => props.onClick(props.option)}\n className={`btn w-100 text-center btn-${props.active ? 'dark' : 'outline-dark'} mb-1`}\n disabled={props.disabled}\n >\n {props.option.name}\n </button>\n\n <span>{mapOptionToDurationRange(props.option)}</span>\n </li>\n );\n}\n\nexport function DurationFilter(props: FilterProps): JSX.Element {\n const currentSelection = ArrayHelper.first(props.draftState.selection);\n\n function onClickDuration(duration: FilterOption<DurationFilterOptions>): void {\n // If the clicked option is already selected, deselect it\n if (currentSelection?.id === duration.id) {\n props.setDraftState({\n active: false,\n selection: []\n });\n \n return;\n }\n\n props.setDraftState({\n active: true,\n selection: [duration]\n });\n }\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n\n <ul className='d-flex list-unstyled flex-column flex-md-row mx-n1 mb-2'>\n {props.filter.options.map(option => (\n <DurationOption\n key={option.id}\n option={option as FilterOption<DurationFilterOptions>}\n onClick={onClickDuration}\n active={currentSelection?.id === option.id}\n disabled={props.filter.disabled || option.disabled}\n />\n ))}\n </ul>\n </>\n );\n}\n","export const XmasConstants = {\n IS_XMAS: false\n};\n",":local{\n .icon {\n width: 1.25rem;\n left: map-get($spacers, 2);\n }\n .activeIcon {\n width: 2.5rem;\n top: -#{map-get($spacers, 1)};\n left: 0.0625rem;\n transform: rotate(-16deg);\n }\n\n .text {\n margin-left: 1.625rem;\n }\n\n .floatingIcon {\n width: 1.875rem;\n transition: all 300ms;\n\n &.default {\n opacity: 0;\n top: -0.5rem;\n left: 1rem;\n }\n &.default.xmas {\n opacity: 0;\n top: 0.3rem;\n left: 0rem;\n }\n &.active {\n opacity: 1;\n top: -1.5rem;\n left: 2rem;\n }\n &.active.xmas {\n opacity: 1;\n scale: 0.8;\n top: -0.91857rem;\n left: 0rem;\n }\n }\n\n}","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterState } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { XmasConstants } from 'libs/shared/constants/XmasConstants';\n\nimport styles from './movies-and-tv-filter.module.scss';\n\nconst namespace = 'search.moviesAndTvFilter';\n\ninterface MoviesAndTvFilterProps {\n filter: SearchFilter;\n iconUrl: string;\n extraIconUrl: string;\n}\n\nexport function MoviesAndTvFilter(props: MoviesAndTvFilterProps): JSX.Element {\n const filter = props.filter;\n const { state } = React.useContext(FilterContext);\n\n const currentFilterState = state[filter.id];\n const isActive = currentFilterState?.active;\n\n // local state to correct attach & detach animation class\n const [ isFloating, setIsFloating ] = React.useState(false);\n const activeRef = React.useRef(isFloating);\n\n React.useEffect(() => {\n if (isActive !== activeRef.current) {\n activeRef.current = isActive;\n }\n if (isFloating !== activeRef.current)\n setIsFloating(activeRef.current);\n }, [isActive]);\n\n function applyFilter(newState: FilterState): void {\n FilterHelper.applyFilter(\n [filter],\n currentFilterState,\n { [props.filter.id]: newState },\n state.appLink\n );\n }\n \n return (\n <DivButton\n onClick={() => {\n setIsFloating(!isActive);\n applyFilter({ active: !isActive });\n }}\n className={classNames(\n 'mx-1 btn position-relative fw-semibold d-flex align-items-center flex-shrink-0',\n isActive ? 'btn-dark' : 'btn-outline-dark',\n props.filter.disabled && 'disabled'\n )}\n disabled={props.filter.disabled}\n >\n \n <img src={props.iconUrl} className={`${styles.icon} position-absolute ${isActive ? styles.activeIcon : ''}`}/>\n \n <div className={styles.text}>\n <Text namespace={namespace} phrase='title'/>\n </div>\n\n <img\n src={props.extraIconUrl}\n className={classNames(\n 'position-absolute',\n styles.floatingIcon,\n isFloating ? styles.active : styles.default,\n XmasConstants.IS_XMAS && styles.xmas\n )}\n />\n </DivButton>\n );\n}\n","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nimport { CheckboxFilterList } from '../checkbox-filter/CheckboxFilterList';\n\nexport function GroupedCheckboxFilter(props: FilterProps): JSX.Element {\n const optionGroups: Record<string, FilterOption[]> = {};\n\n for (const option of props.filter.options) {\n if (!option.group)\n continue;\n\n if (!optionGroups[option.group])\n optionGroups[option.group] = [];\n\n optionGroups[option.group].push(option);\n }\n\n return (\n <Form className='mb-3'>\n {Object.entries(optionGroups).map(([ groupName, options ]) => {\n return (\n <ul className='list-unstyled' key={groupName}>\n <FilterDropdownTitle title={groupName} />\n <CheckboxFilterList\n filter={props.filter}\n options={options}\n draftState={props.draftState}\n setDraftState={props.setDraftState}\n displayOptionsIn2Columns={false}\n />\n </ul>\n );\n })}\n </Form>\n );\n}\n","import { FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\n\nexport const ClassificationFilterHelper = {\n deriveInitialClassificationFilterStateFromQueryParams(filter: SearchFilter, selections: any): FilterOption[] {\n return filter?.options?.filter(option => {\n const areAllIdsInOptionFoundInSelections = option.id.split(':').every(id => {\n const isIdFoundInSelections = selections.find(\n (selectedId: number | string) => selectedId.toString() === id.toString()\n );\n\n return isIdFoundInSelections;\n });\n\n return areAllIdsInOptionFoundInSelections;\n }) ?? [];\n }\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { DurationFilterOptions, FilterOption } from 'libs/shared/apps/search/interfaces';\n\nconst namespace = 'sharedSearch.utils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport const DurationFilterHelper = {\n getOptions(): FilterOption<DurationFilterOptions>[] {\n return [\n {\n id: 'bite-sized',\n name: getPhrase('durationBiteSized')\n },\n {\n id: 'short',\n name: getPhrase('durationShort')\n },\n {\n id: 'medium',\n name: getPhrase('durationMedium')\n },\n {\n id: 'long',\n name: getPhrase('durationLong')\n }\n ];\n },\n\n getBackendParamValue(value: DurationFilterOptions): string {\n switch (value) {\n case 'bite-sized':\n return '...179999'; // 3 minutes in ms\n case 'short':\n return '180000...299999'; // 3 - 5 minutes in ms\n \n case 'medium':\n return '300000...899999'; // 5 - 15 minutes in ms\n \n case 'long':\n return '900000...'; // 15 minutes in ms\n }\n }\n};\n","import { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { FilterOption } from 'libs/shared/apps/search/interfaces';\n\nimport { getSelectedOptions } from './FilterHelper';\n\nexport const PresentationFilterHelper = {\n deriveInitialPresentationFilterStateFromQueryParams:\n (filterOptions: FilterOption[], selections: any, queryParams: HashObject): FilterOption[] => {\n return getSelectedOptions(filterOptions, selections)\n .map(option => {\n const audienceSelection = queryParams['audience'];\n\n if (!audienceSelection?.length)\n return option;\n\n const secondLayerSelection = getSelectedOptions(option.secondLayerOptions, audienceSelection);\n\n return { ...option, secondLayerSelection };\n }).filter(r => {\n return !!r.secondLayerSelection?.length;\n });\n }\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { FilterOption, ProductionYearFilterOptions } from 'libs/shared/apps/search/interfaces';\n\nconst namespace = 'sharedSearch.utils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport const ProductionYearFilterHelper = {\n getOptions(): FilterOption<ProductionYearFilterOptions>[] {\n return [\n {\n id: 'any-year',\n name: getPhrase('anyYear'),\n default: true\n },\n {\n id: 'this-year',\n name: getPhrase('thisYear')\n },\n {\n id: 'last-3-years',\n name: getPhrase('last3Years')\n },\n {\n id: 'last-5-years',\n name: getPhrase('last5Years')\n }\n ];\n },\n\n getBackendParamValue(value: ProductionYearFilterOptions): string {\n const currentYear = new Date().getFullYear();\n \n switch (value) {\n case 'any-year':\n return '';\n \n case 'this-year':\n return `${currentYear}...`;\n \n case 'last-3-years':\n return `${currentYear - 3}...`;\n \n case 'last-5-years':\n return `${currentYear - 5}...`;\n }\n }\n};\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { Rating, User, YearGroup } from 'libs/shared/interfaces';\n\nexport const RatingFilterHelper = {\n deriveInitialRatingFilterStateFromQueryParams(range: string | [], filter: SearchFilter): FilterOption[] {\n /**\n * When the rating filter is cleared, the app router temporarily sets the rating query param\n * value to an empty array instead of a string. In this case, we just return no selections\n */\n if (Array.isArray(range))\n return range;\n\n const ratingOptions = filter.options as Rating[];\n\n const ratingRange = getRatingsFromFrontendQuery(range, ratingOptions);\n\n if (!ratingRange.length)\n return [];\n\n const highestRating = ArrayHelper.last(ratingRange);\n\n return ratingOptions.filter(option => {\n return option.value > 0 && option.value <= highestRating.value;\n }) as FilterOption[];\n },\n\n getFrontendParamValue(selections: Rating[]): string {\n if (!selections?.length)\n return '';\n \n const first = ArrayHelper.first(selections);\n const last = ArrayHelper.last(selections);\n\n if (selections.length === 1)\n return first.code;\n \n return `${first.code}-to-${last.code}`;\n },\n \n getBackendParamValue(range: string, ratings: Rating[]): string {\n const selectedRatings = getRatingsFromFrontendQuery(range, ratings);\n \n if (!selectedRatings.length)\n return undefined;\n \n if (selectedRatings.length === 1) {\n const upperValue = ArrayHelper.first(selectedRatings);\n return `0...${upperValue.value}`;\n }\n \n const upperValue = ArrayHelper.last(selectedRatings);\n return `0...${upperValue.value}`;\n },\n\n getStudentMaxRating(yearGroups: YearGroup[], user: User): Rating {\n const studentYearGroup = ArrayHelper.findWhere(\n yearGroups,\n { value: user.masterYearGroup?.value }\n );\n\n return studentYearGroup?.rating;\n }\n};\n\nfunction getRatingsFromFrontendQuery(range: string, ratings: Rating[]): Rating[] {\n const codes = range.split('-to-');\n const foundRatings = codes.map(code => ratings.find(r => r.code === code));\n\n /**\n * If we can't map all our values, don't use any values.\n */\n if (!foundRatings.every(r => !!r))\n return [];\n\n return foundRatings;\n}\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, FilterDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { CheckboxFilter, DropdownFilter, NestedCheckboxFilter, RadioFilter, SwitchFilter } from 'libs/shared/apps/search/components/filter-types';\nimport { RatingFilter } from 'libs/shared/apps/search/components/filter-types/rating-filter/RatingFilter';\nimport { FilterConstants } from 'libs/shared/apps/search/constants/FilterConstants';\nimport { AllSearchIndicesInSearch, AllSearchIndicesInUserManager, AllSearchIndicesVideoStyle, FilterIds, FilterOption, FilterProps, FilterType, FilterWhitelist, MoreFilters, SearchFilter, SearchIndices } from 'libs/shared/apps/search/interfaces';\nimport { AnalyticsFilterHash } from 'libs/shared/apps/search/interfaces/AnalyticsFilterHash';\nimport { DraftState, FilterPayloadType, FilterState, FilterStateHash } from 'libs/shared/apps/search/reducers';\nimport { SourceFilterHelper } from 'libs/shared/apps/search/utils/SourceFilterHelper';\nimport { TopicsConstants } from 'libs/shared/constants/TopicsConstants';\nimport { BatchJobType } from 'libs/shared/enums/BatchJobType';\nimport { CurationTag } from 'libs/shared/enums/CurationTag';\nimport { CustomerStatus, CustomerStatusString } from 'libs/shared/enums/CustomerStatus';\nimport { CustomerType, CustomerTypeString } from 'libs/shared/enums/CustomerType';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { BaseObject, Customer, Library, MasterNestedObject, PresentationWithAudiences, Rating, SpecialEventType, YearGroup } from 'libs/shared/interfaces';\n\nimport { SpecialEventTypeLabelMap } from '../../calendar/constants/SpecialEventTypeLabelMap';\nimport { BulkUserActionsHelper } from '../../user-manager/utils/BulkUserActionsHelper';\nimport { DurationFilter } from '../components/filter-types/custom/duration-filter/DurationFilter';\nimport { MoviesAndTvFilter } from '../components/filter-types/custom/movies-and-tv-filter/MoviesAndTvFilter';\nimport { GroupedCheckboxFilter } from '../components/filter-types/grouped-checkbox-filter/GroupedCheckboxFilter';\n\nimport { ClassificationFilterHelper } from './ClassificationFilterHelper';\nimport { DurationFilterHelper } from './DurationFilterHelper';\nimport { PresentationFilterHelper } from './PresentationFilterHelper';\nimport { ProductionYearFilterHelper } from './ProductionYearFilterHelper';\nimport { RatingFilterHelper } from './RatingFilterHelper';\nimport { SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM } from './SharedSearchHelper';\n\nconst getPhrase = LanguageService.encloseNamespace('sharedSearch.utils');\n\ntype MixinDisableFieldsFn = {\n mainFilters: SearchFilter[],\n moreFilters?: MoreFilters\n};\n\nconst TwoColumnFilters: Record<string, boolean> = {\n classification: true,\n categoryId: true,\n channel: true\n};\n\ninterface GetValidIndicesOptions {\n hasPartnerProfiles: boolean;\n}\n\nfunction getValidIndices(options: GetValidIndicesOptions): Record<string, boolean> {\n const allIndices: Record<string, boolean> = {\n series: true,\n video: true,\n playlist: true,\n classification: true,\n clip: true,\n interactive: true,\n company: true,\n category: true,\n partner_profile: false\n };\n\n if (options.hasPartnerProfiles) {\n allIndices.partner_profile = true;\n allIndices.company = false;\n }\n \n return allIndices;\n}\n\nexport const Filters: Filters = {\n SortBy: (options: FilterOption[], labelPrefix?: string) => ({\n id: 'sort',\n name: getPhrase('newest'),\n type: 'dropdown',\n options,\n compatibleIndices: [ ...AllSearchIndicesInSearch, ...AllSearchIndicesInUserManager ],\n labelPrefix\n }),\n Presentation: (options: PresentationWithAudiences[], _hasNewSearch: boolean) => ({\n id: 'presentation',\n secondaryId: 'audience',\n name: getPhrase('schoolLevels'),\n type: 'nested-checkbox',\n options: getMappedPresentationOptions(options),\n compatibleIndices: _hasNewSearch ?\n [ 'playlist', 'series', 'clip', 'interactive', 'video', 'company', 'category' ] :\n AllSearchIndicesInSearch\n }),\n Topics: (options: FilterOption[]) => ({\n compatibleIndices: [ 'playlist', 'series', 'clip', 'classification', 'interactive', 'video' ],\n options,\n type: 'checkbox',\n name: getPhrase('topicsFilter'),\n id: 'classification'\n }),\n Source: (options: FilterOption[]) => ({\n id: 'source',\n type: 'checkbox',\n name: getPhrase('sources'),\n options,\n compatibleIndices: [ 'video', 'clip', 'interactive', 'category' ]\n }),\n MoviesAndTv: (url: string, extraUrl: string) => ({\n id: 'moviesAndTv',\n name: getPhrase('moviesAndTv'),\n type: 'button',\n compatibleIndices: [ 'video', 'series', 'clip', 'interactive', 'classification', 'playlist', 'company' ],\n customComponent: props => (\n <MoviesAndTvFilter\n {...props}\n filter={props.filter as SearchFilter}\n iconUrl={url}\n extraIconUrl={extraUrl}\n />\n )\n }),\n YearGroup: (options: FilterOption[]) => ({\n id: 'yearGroup', // \"id\" should match the state keys in `FilterReducer`\n name: getPhrase('yearGroup'),\n type: 'checkbox',\n options,\n compatibleIndices: AllSearchIndicesInUserManager\n }),\n ObjectTypes: (inaccessibleIndices: SearchIndices[] = [], _hasNewSearch = false, _hasPartnerProfiles = false) => ({\n id: 'type',\n name: getPhrase('types'),\n type: _hasNewSearch ? 'grouped-checkbox' : 'checkbox',\n options: FilterHelper.getObjectTypeOptions(inaccessibleIndices, _hasNewSearch, _hasPartnerProfiles),\n disableOptions: FilterHelper.getIsObjectTypeOptionDisabled,\n compatibleIndices: AllSearchIndicesInSearch\n }),\n Rating: (options: FilterOption[], maxRating: Rating) => ({\n id: 'rating',\n name: getPhrase('rating'),\n description: getPhrase('ratingDescription'),\n type: 'rating',\n options: options && maxRating ? options.filter((rating: Rating) => rating.value <= maxRating.value) : options,\n compatibleIndices: [ 'video', 'series' ]\n }),\n Interactives: () => ({\n id: 'interactives',\n name: getPhrase('interactives'),\n type: 'switch',\n description: getPhrase('interactivesDescription'),\n compatibleIndices: [ 'video', 'clip' ]\n }),\n Clips: () => ({\n id: 'clips',\n name: getPhrase('clips'),\n type: 'switch',\n description: getPhrase('clipsDescription'),\n compatibleIndices: ['video']\n }),\n HasResources: () => ({\n id: 'hasResources',\n name: getPhrase('resources'),\n type: 'switch',\n description: getPhrase('resourcesDescription'),\n compatibleIndices: [ 'video', 'clip' ]\n }),\n HasSubtitles: () => ({\n id: 'hasSubtitles',\n name: getPhrase('subtitles'),\n type: 'switch',\n description: getPhrase('subtitlesDescription'),\n compatibleIndices: AllSearchIndicesVideoStyle\n }),\n ProductionYear: () => ({\n id: 'productionYear',\n name: getPhrase('productionYear'),\n type: 'radio',\n options: ProductionYearFilterHelper.getOptions(),\n compatibleIndices: [ ...AllSearchIndicesVideoStyle, 'series' ]\n }),\n IsHD: () => ({\n id: 'isHd',\n name: getPhrase('isHd'),\n type: 'switch',\n description: getPhrase('isHdDescription'),\n compatibleIndices: AllSearchIndicesVideoStyle\n }),\n IsClickViewContent: () => ({\n id: 'producedByClickView',\n name: getPhrase('producedByClickView'),\n type: 'switch',\n description: getPhrase('producedByClickViewDescription'),\n compatibleIndices: AllSearchIndicesInSearch\n }),\n Duration: () => ({\n id: 'duration',\n name: getPhrase('duration'),\n type: 'radio',\n customComponent: DurationFilter,\n options: DurationFilterHelper.getOptions(),\n compatibleIndices: AllSearchIndicesVideoStyle\n }),\n TagOrClassification: (options: string[]) => ({\n id: 'tagOrClassification',\n type: 'tag',\n options: options && options.map(option => ({\n id: option,\n name: option\n })),\n compatibleIndices: AllSearchIndicesInSearch\n }),\n Status: (options?: FilterOption[]) => ({\n id: 'status',\n name: getPhrase('status'),\n type: 'checkbox',\n compatibleIndices: [ ...AllSearchIndicesInUserManager, 'customer' ],\n options: options || FilterHelper.getStatusOptions()\n }),\n JobStatus: () => ({\n id: 'jobStatus',\n name: getPhrase('status'),\n type: 'checkbox',\n compatibleIndices: [],\n options: FilterHelper.getJobStatusOptions()\n }),\n IsAdmin: (customer: Customer, countryCode: string) => {\n const hasOrg = !!customer?.organisation;\n const isUs = countryCode === 'US';\n const description = !hasOrg ? getPhrase('isAdminDescription') :\n isUs ? getPhrase('isAdminDescriptionOrgUs') : getPhrase('isAdminDescriptionOrg');\n\n return {\n id: 'isAdmin',\n name: getPhrase('isAdmin'),\n type: 'switch',\n compatibleIndices: AllSearchIndicesInUserManager,\n description\n };\n },\n BulkActionType: () => ({\n id: 'bulkActionType',\n name: getPhrase('actionType'),\n type: 'checkbox',\n options: BulkUserActionsHelper.getActionTypeFilterOptions(),\n compatibleIndices: []\n }),\n UserType: () => ({\n id: 'userType',\n name: getPhrase('users'),\n type: 'checkbox',\n options: BulkUserActionsHelper.getUserTypeFilterOptions(),\n compatibleIndices: []\n }),\n TvFields: () => ({\n id: 'filter',\n name: getPhrase('tvFields'),\n type: 'radio',\n options: FilterHelper.getTvFieldsOptions(),\n compatibleIndices: []\n }),\n TvChannel: (channels: BaseObject[]) => ({\n id: 'channel',\n name: getPhrase('tvChannel'),\n type: 'checkbox',\n options: FilterHelper.getTvChannelOptions(channels),\n compatibleIndices: []\n }),\n TvDateBroadcast: () => ({\n id: 'dateBroadcast',\n name: getPhrase('tvDateBroadcast'),\n type: 'radio',\n options: FilterHelper.getTvDateBroadcastOptions(),\n compatibleIndices: []\n }),\n Categories: (categories: MasterNestedObject<Library>[]) => ({\n id: 'categoryId',\n name: getPhrase('categories'),\n type: 'checkbox',\n options: FilterHelper.getCategoriesOptions(categories),\n compatibleIndices: []\n }),\n CustomerStatus: () => ({\n id: 'customerStatus',\n name: getPhrase('customerStatus'),\n type: 'radio',\n options: FilterHelper.getCustomerStatusOptions(),\n compatibleIndices: []\n }),\n SpecialEventTypes: () => ({\n id: 'specialEventType',\n type: 'checkbox',\n name: 'Event Type',\n compatibleIndices: [],\n options: FilterHelper.getSpecialEventTypeOptions()\n }),\n CustomerType: () => ({\n id: 'customerType',\n name: getPhrase('customerType'),\n type: 'radio',\n options: FilterHelper.getCustomerTypeOptions(),\n compatibleIndices: []\n })\n};\n\ninterface Filters {\n SortBy: (options: FilterOption[], labelPrefix?: string) => SearchFilter;\n Presentation: (options: PresentationWithAudiences[], _hasNewSearch?: boolean) => SearchFilter;\n Topics: (options: FilterOption[]) => SearchFilter;\n YearGroup: (options: FilterOption[]) => SearchFilter;\n MoviesAndTv: (iconUrl: string, extraUrl: string) => SearchFilter;\n ObjectTypes: (\n inaccessibleIndices: SearchIndices[],\n _hasNewSearch?: boolean,\n _hasPartnerProfiles?: boolean\n ) => SearchFilter;\n Rating: (options: FilterOption[], maxRating: Rating) => SearchFilter;\n Interactives: () => SearchFilter;\n Clips: () => SearchFilter;\n HasResources: () => SearchFilter;\n HasSubtitles: () => SearchFilter;\n ProductionYear: () => SearchFilter;\n IsHD: () => SearchFilter;\n IsClickViewContent: () => SearchFilter;\n Duration: () => SearchFilter;\n TagOrClassification: (options: string[]) => SearchFilter;\n Status: (options?: FilterOption[]) => SearchFilter;\n JobStatus: () => SearchFilter;\n IsAdmin: (customer?: Customer, countryCode?: string) => SearchFilter;\n BulkActionType: () => SearchFilter<BatchJobType>;\n UserType: () => SearchFilter<UserGroup>;\n TvFields: () => SearchFilter;\n TvChannel: (channels: BaseObject[]) => SearchFilter;\n TvDateBroadcast: () => SearchFilter;\n Categories: (categories: MasterNestedObject<Library>[]) => SearchFilter;\n Source: (options: FilterOption[]) => SearchFilter;\n CustomerStatus: () => SearchFilter;\n SpecialEventTypes: () => SearchFilter;\n CustomerType: () => SearchFilter;\n}\n\nfunction getMappedPresentationOptions(options: PresentationWithAudiences[]): FilterOption[] {\n if (!options)\n return [];\n\n return options.map(opt => ({\n ...opt,\n id: opt.id.toString(),\n secondLayerOptions: opt.audiences.map(a => ({ ...a, id: a.id.toString() }))\n }));\n}\n\nexport const FilterHelper = {\n displayTwoLayers(filter: SearchFilter): boolean {\n if (filter.type !== 'nested-checkbox')\n return false;\n\n // With one presso we only show second layer options\n if (!this.hasManyFilterOptions(filter.options))\n return false;\n\n // Show first layer only\n if (filter.options.every(o => !this.hasManyFilterOptions(o?.secondLayerOptions)))\n return false;\n\n return true;\n },\n\n hasManyFilterOptions(options: FilterOption[]) {\n return options.length >= TopicsConstants.MULTI_PRESENTATION_THRESHOLD;\n },\n\n displayTwoColumns(filter: SearchFilter | MoreFilters): boolean {\n return (\n (TwoColumnFilters[filter.id]) &&\n filter.options?.length >= FilterConstants.MAX_CHECKBOXES_PER_COLUMN\n );\n },\n\n showPresentationFilter(presentationFilter: SearchFilter): boolean {\n // If the school's topic presentation has no audiences, don't show\n if (!presentationFilter.options?.length)\n return false;\n\n // If the school has more than 1 topic presentation, always show\n if (presentationFilter.options.length > 1)\n return true;\n \n // If the school has only 1 topic presentation but it has >1 audience, always show\n if (ArrayHelper.first(presentationFilter.options).secondLayerOptions?.length > 1)\n return true;\n\n return false;\n },\n\n getMoreFilters(filters: SearchFilter[]): MoreFilters {\n return {\n id: 'moreFilters',\n name: getPhrase('moreFilters'),\n type: 'more-filters',\n filters\n };\n },\n\n mapTypeToComponent(type: FilterType): (props: FilterProps) => JSX.Element {\n switch (type) {\n case 'switch':\n return (props: any) => <SwitchFilter key={props.id} {...props} />;\n case 'checkbox':\n return (props: any) => <CheckboxFilter key={props.id} {...props} />;\n case 'nested-checkbox':\n return (props: any) => <NestedCheckboxFilter key={props.id} {...props} />;\n case 'grouped-checkbox':\n return (props: any) => <GroupedCheckboxFilter key={props.id} {...props} />;\n case 'radio':\n return (props: any) => <RadioFilter key={props.id} {...props} />;\n case 'rating':\n return (props: any) => <RatingFilter key={props.id} {...props} />;\n case 'dropdown':\n return (props: any) => <DropdownFilter key={props.id} {...props} />;\n default:\n return () => <></>;\n }\n },\n\n deriveInitialStateFromQuery(\n queryParams: HashObject = {},\n mainFilters: SearchFilter[] = null,\n moreFilters: MoreFilters = null,\n appLink: Core.AppLink\n ): FilterStateHash {\n const initialStates: Omit<FilterStateHash, 'appLink' | 'moreFilters'> = {\n sort: {\n active: !!queryParams.sort,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'sort')\n },\n\n classification: {\n active: !!queryParams.classification,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'classification')\n },\n\n presentation: {\n active: !!queryParams.presentation,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'presentation')\n },\n\n type: {\n active: !!queryParams.type,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'type')\n },\n\n specialEventType: {\n active: !!queryParams.specialEventType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'specialEventType')\n },\n\n rating: {\n active: !!queryParams.rating,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'rating')\n },\n \n interactives: {\n active: queryParams.interactives?.toString() === 'true'\n },\n\n clips: {\n active: queryParams.clips?.toString() === 'true'\n },\n\n yearGroup: {\n active: !!queryParams.yearGroup,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'yearGroup')\n },\n\n moviesAndTv: {\n active: queryParams.moviesAndTv?.toString() === 'true'\n },\n\n classroom: {\n active: !!queryParams.classroom,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'classroom')\n },\n\n audience: {\n active: !!queryParams.audience,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'audience')\n },\n\n hasResources: {\n active: queryParams.hasResources?.toString() === 'true'\n },\n\n hasSubtitles: {\n active: queryParams.hasSubtitles?.toString() === 'true'\n },\n\n productionYear: {\n active: !!queryParams.productionYear,\n selection: getFilterSelectionsFromQueryParams(queryParams, moreFilters?.filters, 'productionYear')\n },\n\n isHd: {\n active: queryParams.isHd?.toString() === 'true'\n },\n\n producedByClickView: {\n active: queryParams.producedByClickView?.toString() === 'true'\n },\n\n duration: {\n active: queryParams.duration,\n selection: getFilterSelectionsFromQueryParams(queryParams, moreFilters?.filters, 'duration')\n },\n\n tagOrClassification: {\n active: !!queryParams.tagOrClassification,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'tagOrClassification')\n },\n\n status: {\n active: !!queryParams.status,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'status')\n },\n\n jobStatus: {\n active: !!queryParams.jobStatus,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'jobStatus')\n },\n isAdmin: {\n active: queryParams.isAdmin?.toString() === 'true'\n },\n\n bulkActionType: {\n active: !!queryParams.bulkActionType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'bulkActionType')\n },\n\n userType: {\n active: !!queryParams.userType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'userType')\n },\n\n filter: {\n active: !!queryParams.filter,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'filter')\n },\n\n channel: {\n active: !!queryParams.channel,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'channel')\n },\n\n dateBroadcast: {\n active: !!queryParams.dateBroadcast,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'dateBroadcast')\n },\n\n categoryId: {\n active: !!queryParams.categoryId,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'categoryId')\n },\n \n hasInteractives: {\n active: !!queryParams.hasInteractives,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'hasInteractives')\n },\n\n source: {\n active: !!queryParams.source,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'source')\n },\n\n customerStatus: {\n active: !!queryParams.customerStatus,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'customerStatus')\n },\n\n customerType: {\n active: !!queryParams.customerType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'customerType')\n },\n\n seriesId: {\n active: !!queryParams.seriesId,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'seriesId')\n },\n\n scopeId: {\n active: !!queryParams.scopeId,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'scopeId')\n }\n };\n\n const reduceFunc = (state: FilterStateHash, filter: SearchFilter<string>) => {\n const filterState = initialStates[filter.id];\n\n /**\n * If we had the query param value, but were not able to parse it into a valid selection.\n * We're actually not active.\n * \n * e.g. For `?rating=bleep-to-bloop` the value of !!queryParams.rating is true, but we are not able\n * to extract any meaningful values from it so the call to getFilterSelectionsFromQueryParams returns an empty array.\n * \n * - Sha\n */\n if (filterState.active && 'selection' in filterState && !filterState.selection?.length)\n filterState.active = false;\n\n state[filter.id] = initialStates[filter.id];\n return state;\n };\n\n const derivedState = mainFilters.reduce<FilterStateHash>(reduceFunc, {} as FilterStateHash);\n\n if (moreFilters?.filters) {\n derivedState.moreFilters = moreFilters.filters.reduce<FilterStateHash>(reduceFunc, {} as FilterStateHash);\n }\n\n derivedState.appLink = appLink;\n\n return derivedState;\n },\n\n hasActiveFilters(queryParams: HashObject): boolean {\n const paramKeys = Object.keys(queryParams);\n\n if (!paramKeys.length)\n return false;\n\n const activeFilters = paramKeys.filter(q => {\n // 'query', 'cursor', 'page', 'scopeId' and 'curriculumCode' don't count as filters\n if ([ 'query', 'cursor', 'page', SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM ].includes(q))\n return false;\n\n // Filters that can have multiple selections (e.g. checkbox types) do not count as active if they are empty\n if (Array.isArray(queryParams[q]) && !queryParams[q].length)\n return false;\n\n return true;\n });\n\n return !!activeFilters.length;\n },\n\n getLabel(filter: SearchFilter, filterState: FilterState): string {\n if (!filterState?.selection?.length)\n return filter.name;\n\n if (filter.type === 'dropdown')\n return ArrayHelper.first(filterState.selection).name;\n\n if (filter.type === 'radio') {\n const selection = ArrayHelper.first(filterState.selection);\n if (!selection || selection.default)\n return filter.name;\n\n return selection.name;\n }\n\n if (filter.type === 'nested-checkbox' || filter.type === 'checkbox' || filter.type === 'grouped-checkbox') {\n const isDefaultState = filter.options.find(opt => {\n return opt.default && filterState.selection.find(selection => selection.id === opt.id);\n });\n\n if (isDefaultState)\n return filter.name;\n\n if (filter.secondaryId) {\n const count = filterState.selection?.reduce((acc, firstLayerSelection) => {\n const availableOptions = filter.options;\n const index = availableOptions.findIndex(option => option.id === firstLayerSelection.id);\n if (availableOptions[index].secondLayerOptions?.length === 0) {\n return acc + 1;\n }\n\n return acc + (firstLayerSelection.secondLayerSelection?.length ?? 0);\n }, 0);\n\n return `${filter.name} - ${count}`;\n }\n\n return `${filter.name} - ${filterState.selection.length}`;\n }\n\n if (filter.type === 'rating') {\n if (!filterState.selection.length)\n return filter.name;\n\n const first = ArrayHelper.first(filterState.selection) as Rating;\n const last = ArrayHelper.last(filterState.selection) as Rating;\n\n if (filterState.selection.length === 1)\n return `${filter.name}: ${first.code}`;\n\n return `${filter.name}: ${first.code} to ${last.code}`;\n }\n },\n\n buildFrontendFilterParams(queryParams: HashObject, filterStates: Array<FilterPayloadType>): HashObject {\n const updatedParams = { ...queryParams };\n\n filterStates.forEach(filterState => {\n if (!filterState?.filter)\n return;\n\n const { id: param, type } = filterState.filter;\n const { active, selection } = filterState.state;\n\n switch (type) {\n case 'switch':\n updatedParams[param] = active ? 'true' : '';\n break;\n\n case 'radio':\n case 'dropdown':\n const isDefault =\n filterState.state.selection?.length === 1 && ArrayHelper.first(filterState.state.selection)?.default;\n\n updatedParams[param] = (filterState.state.selection.length && !isDefault) ? ArrayHelper.first(filterState.state.selection).id : '';\n break;\n\n case 'nested-checkbox':\n updatedParams[param] = active ? selection.map(option => option.id) : null;\n const { secondaryId: secondaryParam } = filterState.filter;\n\n if (secondaryParam) {\n // FlatMap\n updatedParams[secondaryParam] = [].concat(...selection.map(s => s.secondLayerSelection.map(o => o.id)));\n }\n\n break;\n\n case 'checkbox':\n case 'grouped-checkbox':\n if (!active) {\n updatedParams[param] = null;\n break;\n }\n\n const options = [];\n for (const option of selection) {\n const ids = option.id.toString().split(':');\n if (ids.length > 1) {\n // When an option has more than one id\n // e.g. An topic option can used by many presentations\n for (const id of ids) {\n options.push(id);\n }\n } else {\n options.push(option.id);\n }\n }\n\n updatedParams[param] = options;\n break;\n\n case 'tag':\n updatedParams[param] = active ? selection.map(option => option.id) : null;\n break;\n\n case 'rating':\n updatedParams[param] = active ? RatingFilterHelper.getFrontendParamValue(selection as Rating[]) : null;\n break;\n\n case 'button':\n updatedParams[param] = active ? 'true' : '';\n break;\n }\n\n if (!updatedParams[param]) // If the param is empty, delete it\n delete updatedParams[param];\n });\n\n return ObjectHelper.omit(updatedParams, ['cursor']);\n },\n\n buildBackendFilterParams(\n queryParams: HashObject,\n ratings: Rating[] = [],\n presentationIds: string[],\n isLearner: boolean,\n libraries: Library[],\n streamableLibraryId?: string\n ): HashObject {\n const defaultParams: HashObject = isLearner ? {\n ['filters.presentation']: presentationIds,\n isLearner\n } : {};\n\n return Object.keys(queryParams).reduce((acc: HashObject, paramName: FilterIds) => {\n const values = queryParams[paramName];\n\n if ((Array.isArray(values) && !values.length) || !values)\n return acc;\n\n if (!FilterWhitelist[paramName])\n return acc;\n\n if (paramName === 'rating') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = RatingFilterHelper.getBackendParamValue(values, ratings);\n return acc;\n }\n\n if (paramName === 'productionYear') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = ProductionYearFilterHelper.getBackendParamValue(values);\n return acc;\n }\n\n if (paramName === 'duration') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = DurationFilterHelper.getBackendParamValue(values);\n return acc;\n }\n\n if (paramName === 'moviesAndTv') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}curationTag`] = CurationTag.MOVIES_AND_TV;\n return acc;\n }\n\n if (paramName === 'source') {\n return {\n ...acc,\n ...SourceFilterHelper.getBackendParamValue(values, libraries, streamableLibraryId)\n };\n }\n\n if (paramName === 'scopeId') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}partnerProfile`] = [values];\n return acc;\n }\n\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = values;\n\n return acc;\n }, defaultParams);\n },\n\n getAppliedIndices(\n queryParams: HashObject = {},\n _hasNewSearch: boolean = false,\n _hasPartnerProfiles: boolean = false\n ): SearchIndices[] {\n const { type: indices } = queryParams;\n\n const validIndices = getValidIndices({ hasPartnerProfiles: _hasPartnerProfiles });\n \n const newIndices: SearchIndices[] = ['category'];\n\n function validateIndices(indice: SearchIndices): boolean {\n if (_hasNewSearch) {\n return validIndices[indice];\n }\n\n return !newIndices.includes(indice) && validIndices[indice];\n }\n\n if (indices) {\n if (!Array.isArray(indices))\n return [indices].filter(validateIndices);\n\n if (indices.length)\n return indices.filter(validateIndices);\n }\n\n const extraIndices: SearchIndices[] = [];\n if (_hasNewSearch)\n extraIndices.push(...newIndices);\n \n if (queryParams.source)\n return [ 'video', 'clip', 'interactive', ...extraIndices ];\n\n if (_hasPartnerProfiles)\n return [ 'series', 'video', 'playlist', 'classification', 'clip', 'interactive', 'partner_profile', ...extraIndices ];\n\n return [ 'series', 'video', 'playlist', 'classification', 'clip', 'interactive', 'company', ...extraIndices ];\n },\n\n applyFilter(\n filters: Array<SearchFilter>,\n currentFilterState: FilterState | FilterStateHash,\n draftState: DraftState,\n baseAppLink: Core.AppLink\n ): void {\n if (ObjectHelper.isEqual(currentFilterState, draftState))\n return;\n\n const filterIds = Object.keys(draftState) as FilterIds[];\n\n const payload: Array<FilterPayloadType> = filterIds.map(filterId => {\n const filter = filters.find(f => f.id === filterId);\n const draftFilterState = draftState[filterId];\n\n const isDefaultValue =\n draftFilterState.selection?.length === 1 && ArrayHelper.first(draftFilterState.selection)?.default;\n\n return {\n filter,\n state: {\n active: draftFilterState.active && !isDefaultValue,\n selection: draftFilterState.selection\n }\n };\n });\n\n const currentQueryParams = Core.LocationUtils.GetQuery();\n Core.AppLinkHelper.trigger({\n ...baseAppLink,\n params: FilterHelper.buildFrontendFilterParams(currentQueryParams, payload)\n }, { replace: true });\n },\n\n mixinDisabledFields(\n state: FilterStateHash,\n indices: SearchIndices[],\n mainFilters: SearchFilter[],\n moreFilters?: MoreFilters\n ): MixinDisableFieldsFn {\n let allFilters = [ ...mainFilters, ...(moreFilters?.filters ?? []) ];\n\n // Iterate through each filter, and disable them if they should be disabled\n allFilters = disableFilters(state, allFilters, indices);\n\n // Iterate through each filter option, and disable them if they should be disabled\n allFilters = disableFilterOptions(state, allFilters);\n\n const response: MixinDisableFieldsFn = {\n mainFilters: allFilters.filter(filter => mainFilters.find(f => f.id === filter.id))\n };\n\n if (moreFilters?.filters) {\n response.moreFilters = {\n ...moreFilters,\n filters: allFilters.filter(filter => moreFilters.filters.find(f => f.id === filter.id))\n };\n }\n\n return response;\n },\n\n logFilterEvent(\n mainFilters: SearchFilter[],\n moreFilters: MoreFilters,\n state: FilterStateHash,\n query: string,\n analyticsOptions: AnalyticsOptions\n ): void {\n const analyticsFilterObjects: AnalyticsFilterHash[] = [];\n\n mainFilters?.forEach(f => {\n const filterState = state[f.id];\n\n if (filterState.active) {\n analyticsFilterObjects.push({\n type: f.id,\n selection: filterState.selection\n });\n }\n });\n\n moreFilters?.filters?.forEach(f => {\n const filterState = state.moreFilters[f.id];\n\n if (filterState.active) {\n analyticsFilterObjects.push({\n type: f.id,\n selection: filterState.selection\n });\n }\n });\n\n if (!analyticsFilterObjects.length)\n analyticsOptions.descriptor = FilterDescriptor.Reset;\n\n AnalyticsHelper.logUserAction({\n query: query ?? '',\n filters: analyticsFilterObjects\n }, AnalyticsHelper.mergeOptions(analyticsOptions, {\n workflowPhase: WorkflowPhase.Complete,\n actionType: UserAction.Filter\n }));\n },\n\n /**\n * Helpers below this comment return hard coded filter options for a particular filter.\n * If you are adding a new filter with hard coded options, add a new function here.\n */\n getObjectTypeOptions(\n inaccessibleIndices: SearchIndices[] = [],\n _hasNewSearch: boolean,\n _hasPartnerProfiles: boolean\n ): FilterOption<SearchIndices>[] {\n if (_hasNewSearch) {\n const options: FilterOption<SearchIndices>[] = [\n {\n id: 'video',\n name: getPhrase('videos'),\n group: getPhrase('videoTypes')\n },\n {\n id: 'interactive',\n name: getPhrase('interactives'),\n group: getPhrase('videoTypes')\n },\n {\n id: 'clip',\n name: getPhrase('clips'),\n group: getPhrase('videoTypes')\n },\n {\n id: 'classification',\n name: getPhrase('topics'),\n group: getPhrase('collections')\n },\n {\n id: 'series',\n name: getPhrase('series'),\n group: getPhrase('collections')\n },\n {\n id: 'playlist',\n name: getPhrase('playlists'),\n group: getPhrase('collections')\n },\n {\n id: 'category',\n name: getPhrase('category'),\n group: getPhrase('collections')\n }\n ];\n \n if (_hasPartnerProfiles) {\n options.push({\n id: 'partner_profile',\n name: getPhrase('channels'),\n group: getPhrase('collections')\n });\n }\n \n return options.filter(opt => !inaccessibleIndices.find(i => i === opt.id)) as FilterOption<SearchIndices>[];\n }\n\n return [\n {\n id: 'classification',\n name: getPhrase('topics')\n },\n {\n id: 'playlist',\n name: getPhrase('playlists')\n },\n {\n id: 'series',\n name: getPhrase('series')\n },\n {\n id: 'video',\n name: getPhrase('videos')\n },\n {\n id: 'clip',\n name: getPhrase('clips')\n },\n {\n id: 'interactive',\n name: getPhrase('interactives')\n }\n ].filter(opt => !inaccessibleIndices.find(i => i === opt.id)) as FilterOption<SearchIndices>[];\n },\n\n /**\n * Loops through each option on the \"object type\" filter, and determines whether\n * they should be disabled based on the currently active filters\n */\n getIsObjectTypeOptionDisabled(\n options: FilterOption<SearchIndices>[],\n filters: SearchFilter[],\n state: FilterStateHash\n ): FilterOption<SearchIndices>[] {\n return options.map(option => {\n let isDisabled = false;\n\n filters.forEach(filter => {\n if (isDisabled)\n return;\n\n const filterState = state[filter.id] || state.moreFilters[filter.id];\n\n if (!filterState?.active || !filter.compatibleIndices?.length)\n return;\n\n if (!filter.compatibleIndices.find(i => option.id === i))\n isDisabled = true;\n });\n\n return {\n ...option,\n disabled: isDisabled\n };\n });\n },\n\n getNameSortOptions(): FilterOption[] {\n return [\n {\n id: 'newest',\n name: getPhrase('newest')\n },\n {\n id: 'oldest',\n name: getPhrase('oldest')\n },\n {\n id: 'first-name-atoz',\n name: getPhrase('firstNameAToZ')\n },\n {\n id: 'first-name-ztoa',\n name: getPhrase('firstNameZToA')\n },\n {\n id: 'surname-atoz',\n name: getPhrase('surnameAToZ')\n },\n {\n id: 'surname-ztoa',\n name: getPhrase('surnameZToA')\n }\n ];\n },\n\n getYearGroupOptions(yearGroups: YearGroup[]): FilterOption[] {\n if (!yearGroups?.length)\n return [];\n\n return yearGroups.map(y => ({\n id: y.value.toString(),\n name: y.name\n }));\n },\n\n getStatusOptions(): FilterOption[] {\n return [\n {\n id: 'active',\n name: getPhrase('active')\n },\n {\n id: 'deactivated',\n name: getPhrase('deactivated')\n },\n {\n id: 'pending',\n name: getPhrase('pending')\n }\n ];\n },\n\n getJobStatusOptions(): FilterOption[] {\n return [\n {\n id: 'completed',\n name: getPhrase('completed')\n },\n {\n id: 'failed',\n name: getPhrase('errored')\n },\n {\n id: 'inProgress',\n name: getPhrase('inProgress')\n }\n ];\n },\n\n getTvFieldsOptions(): FilterOption[] {\n return [\n {\n id: '0',\n name: getPhrase('allFields'),\n default: true\n },\n {\n id: '1',\n name: getPhrase('titleDescriptionField')\n },\n {\n id: '2',\n name: getPhrase('captionsField')\n }\n ];\n },\n\n getTvChannelOptions(channels: BaseObject[]): FilterOption[] {\n if (!channels?.length)\n return [];\n\n return channels.map(channel => ({\n id: channel.name,\n name: channel.name\n }));\n },\n\n getTvDateBroadcastOptions(): FilterOption[] {\n return [\n {\n id: 'any-time',\n name: getPhrase('anyTime'),\n default: true\n },\n {\n id: 'yesterday',\n name: getPhrase('yesterday')\n },\n {\n id: 'last-week',\n name: getPhrase('lastWeek')\n },\n {\n id: 'last-2-weeks',\n name: getPhrase('last2Weeks')\n }\n ];\n },\n\n getCustomerStatusOptions(): FilterOption[] {\n return [\n {\n id: CustomerStatus.Unclassified.toString(),\n name: CustomerStatusString.Unclassified\n },\n {\n id: CustomerStatus.Active.toString(),\n name: CustomerStatusString.Active\n },\n {\n id: CustomerStatus.Prospect.toString(),\n name: CustomerStatusString.Prospect\n },\n {\n id: CustomerStatus.LostCustomer.toString(),\n name: CustomerStatusString.LostCustomer\n },\n {\n id: CustomerStatus.Disabled.toString(),\n name: CustomerStatusString.Disabled\n },\n {\n id: CustomerStatus.Other.toString(),\n name: CustomerStatusString.Other\n }\n ];\n },\n\n getCustomerTypeOptions(): FilterOption[] {\n return [\n {\n id: CustomerType.Unclassified.toString(),\n name: CustomerTypeString.Unclassified\n },\n {\n id: CustomerType.Primary.toString(),\n name: CustomerTypeString.Primary\n },\n {\n id: CustomerType.Secondary.toString(),\n name: CustomerTypeString.Secondary\n },\n {\n id: CustomerType.K12.toString(),\n name: CustomerTypeString.K12\n },\n {\n id: CustomerType.Tertiary.toString(),\n name: CustomerTypeString.Tertiary\n },\n {\n id: CustomerType.NonEducational.toString(),\n name: CustomerTypeString.NonEducational\n },\n {\n id: CustomerType.Partners.toString(),\n name: CustomerTypeString.Partners\n },\n {\n id: CustomerType.Internal.toString(),\n name: CustomerTypeString.Internal\n },\n {\n id: CustomerType.Other.toString(),\n name: CustomerTypeString.Other\n },\n {\n id: CustomerType.ClickView.toString(),\n name: CustomerTypeString.ClickView\n },\n {\n id: CustomerType.System.toString(),\n name: CustomerTypeString.System\n }\n ];\n },\n \n getCategoriesOptions(categories: MasterNestedObject<Library>[]): FilterOption[] {\n if (!categories?.length)\n return [];\n\n // TODO: Custom nested checkbox\n return categories.map(category => {\n return {\n id: category.data.id,\n name: category.data.name\n // secondLayerOptions: category.children.map(\n // nestedCategory => ({ id: nestedCategory.data.id, name: nestedCategory.data.name })\n // )\n };\n });\n },\n\n getSpecialEventTypeOptions(): FilterOption[] {\n return [\n {\n id: SpecialEventType.BreakingNews,\n name: SpecialEventTypeLabelMap[SpecialEventType.BreakingNews]\n },\n {\n id: SpecialEventType.SportingEvent,\n name: SpecialEventTypeLabelMap[SpecialEventType.SportingEvent]\n },\n {\n id: SpecialEventType.Observance,\n name: SpecialEventTypeLabelMap[SpecialEventType.Observance]\n },\n {\n id: SpecialEventType.NaturalDisaster,\n name: SpecialEventTypeLabelMap[SpecialEventType.NaturalDisaster]\n },\n {\n id: SpecialEventType.HistoricalEvent,\n name: SpecialEventTypeLabelMap[SpecialEventType.HistoricalEvent]\n },\n {\n id: SpecialEventType.Holiday,\n name: SpecialEventTypeLabelMap[SpecialEventType.Holiday]\n },\n {\n id: SpecialEventType.Informal,\n name: SpecialEventTypeLabelMap[SpecialEventType.Informal]\n },\n {\n id: SpecialEventType.ReligiousEvent,\n name: SpecialEventTypeLabelMap[SpecialEventType.ReligiousEvent]\n },\n {\n id: SpecialEventType.Other,\n name: SpecialEventTypeLabelMap[SpecialEventType.Other]\n }\n ];\n }\n};\n\n// This allows us to determine which filters should be applied based on the query params set on first load\nfunction getFilterSelectionsFromQueryParams(\n queryParams: HashObject,\n filters: SearchFilter[] = [],\n filterId: FilterIds\n): FilterOption[] {\n const filter = filters.find(f => f.id === filterId);\n\n if (!filter)\n return [];\n\n if (!queryParams[filterId])\n return filter.options?.filter(option => option.default) ?? [];\n\n if (filterId === 'rating')\n return RatingFilterHelper.deriveInitialRatingFilterStateFromQueryParams(queryParams[filterId], filter);\n\n let selections = queryParams[filterId];\n\n if (!Array.isArray(selections))\n selections = [selections];\n\n if (filterId === 'classification') {\n return ClassificationFilterHelper.deriveInitialClassificationFilterStateFromQueryParams(filter, selections);\n }\n\n if (filterId === 'presentation') {\n return PresentationFilterHelper.\n deriveInitialPresentationFilterStateFromQueryParams(filter.options, selections, queryParams);\n }\n\n return getSelectedOptions(filter.options, selections);\n}\n\nexport function getSelectedOptions(options: FilterOption[] | undefined, selections: any): any[] {\n if (!Array.isArray(selections))\n selections = [selections];\n\n return options?.filter(option => {\n return selections.find((id: number | string) => id.toString() === option.id.toString());\n }) ?? [];\n}\n\n/**\n * This basically iterates through every filter, and works out if that filter should be disabled.\n * This is based on:\n * - If the filter is compatible with any of the currently applied search indices\n * - If the filter is compatible with any of the filter indices that are compatible with any of the active filters\n */\nfunction disableFilters(state: FilterStateHash, filters: SearchFilter[], indices: SearchIndices[]): SearchFilter[] {\n // Convert the currently applied search indices into a hashmap\n const appliedIndices = indices.reduce((acc: HashObject, index) => {\n acc[index] = true;\n return acc;\n }, {});\n\n return filters.map(filter => {\n if (!filter.compatibleIndices?.length)\n return filter;\n\n // If none of the applied indices works with the filter, it should be disabled.\n // For example, if the user filters by \"playlists\", the \"has resources\" filter will be disabled.\n if (!filter.compatibleIndices.find(i => appliedIndices[i])) {\n return {\n ...filter,\n disabled: true\n };\n }\n \n // Get all currently active filters\n const activeFilterIds = Object.keys(state).filter((filterId: keyof typeof state) => {\n const filterState = state[filterId];\n\n if (!('active' in filterState))\n return false;\n\n return filterState.active;\n });\n\n let shouldDisableFilter = false;\n\n activeFilterIds.forEach(activeFilterId => {\n if (shouldDisableFilter)\n return;\n\n const activeFilter = filters.find(f => f.id === activeFilterId);\n\n if (!activeFilter.compatibleIndices?.length)\n return;\n\n const activeFilterIndices = activeFilter.compatibleIndices.reduce((acc: HashObject, index) => {\n acc[index] = true;\n return acc;\n }, {});\n\n /**\n * Check if the active filter's indices are compatible with the current filter's indices.\n * For example, if the \"has resources\" filter is active, then all filters that are incompatible\n * with videos will be disabled.\n */\n if (!filter.compatibleIndices.find(i => activeFilterIndices[i]))\n shouldDisableFilter = true;\n });\n\n return {\n ...filter,\n disabled: shouldDisableFilter\n };\n });\n}\n\n/**\n * This will disable particular option on a filter if they are incompatible with the currently\n * active filters.\n *\n * For example, if we apply the \"rating\" filter, then the \"playlist\" and \"classification\" options\n * on the \"ObjectTypes\" filter will be disabled, as we cannot filter by those options _and_ by rating\n * at the same time.\n */\nfunction disableFilterOptions(state: FilterStateHash, filters: SearchFilter[]): SearchFilter[] {\n return filters.map(filter => {\n if (!FunctionHelper.isFunction(filter.disableOptions))\n return filter;\n\n // Only filters that have a `disableOptions` function will run here.\n const options = filter.disableOptions(filter.options, filters, state);\n\n return {\n ...filter,\n options\n };\n });\n}\n",":local {\n .hideCaret::after {\n display: none;\n }\n\n .filterMenu {\n min-width: 10rem;\n width: max-content;\n\n &.twoColumnsWidth {\n max-width: 35rem;\n \n @media screen and (max-width: #{map-get($grid-breakpoints, md) - 1px}) {\n max-width: 20rem;\n }\n }\n\n &.nestedCheckboxesWidth {\n min-width: 12rem;\n }\n\n &.switchWidth {\n max-width: 15rem;\n }\n }\n\n .moreFiltersWidth {\n width: 25rem;\n max-width: calc(100vw - map-get($spacers, 4));\n }\n\n // Icon positioning adjustments to make it look nicer\n .svgContainer {\n margin-top: 0.05rem;\n margin-right: 0.2rem;\n margin-left: -0.2rem;\n }\n}\n","import * as React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { FilterActions } from 'libs/shared/apps/search/components/filter-actions/FilterActions';\nimport { SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterState } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\n\nimport styles from './filter-button.module.scss';\n\n/**\n * If your filter requires some customisations to the default width, add a use case here.\n */\nfunction getCustomWidthClass(filter: SearchFilter): string {\n if (FilterHelper.displayTwoColumns(filter))\n return styles.twoColumnsWidth;\n\n // Some classifications has long names, so we make them wider\n if (filter.id === 'classification')\n return styles.classificationWidth;\n \n if (FilterHelper.displayTwoLayers(filter))\n return styles.nestedCheckboxesWidth;\n\n if (filter.type === 'switch')\n return styles.switchWidth;\n\n return '';\n}\n\nFilterButton.defaultProps = {\n hideCaret: true\n};\n\ninterface FilterButtonProps {\n filter: SearchFilter;\n hideCaret?: boolean;\n}\n\nexport function FilterButton(props: FilterButtonProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n const currentFilterState = state[props.filter.id];\n\n const isDropdownFilter = props.filter.type === 'dropdown';\n\n const [ label, setLabel ] = React.useState(props.filter.name);\n const [ showDropdown, setShowDropdown ] = React.useState(false);\n const [ draftState, setDraftState ] = React.useState<FilterState>(currentFilterState);\n\n React.useEffect(() => {\n setLabel(FilterHelper.getLabel(props.filter, currentFilterState));\n setDraftState(currentFilterState);\n }, [ props.filter, currentFilterState?.selection ]);\n\n function onSelectItem(state: FilterState): void {\n setDraftState(state);\n\n if (isDropdownFilter)\n applyFilter(state);\n }\n\n function onClickReset(): void {\n const defaultOption = props.filter.options?.find(o => o.default);\n\n setDraftState({\n active: false,\n selection: defaultOption ? [defaultOption] : []\n });\n }\n\n function onClickApply(): void {\n applyFilter();\n setShowDropdown(false);\n }\n\n function applyFilter(newState: FilterState = draftState): void {\n FilterHelper.applyFilter(\n [props.filter],\n currentFilterState,\n { [props.filter.id]: newState },\n state.appLink\n );\n }\n\n function onToggleDropdown(isShowing: boolean): void {\n setShowDropdown(isShowing);\n\n if (isShowing || isDropdownFilter)\n return;\n\n // Apply the filter if the dropdown has been closed\n applyFilter();\n }\n\n const FilterComponent = React.useMemo(() => {\n return props.filter.customComponent ?\n props.filter.customComponent :\n FilterHelper.mapTypeToComponent(props.filter.type);\n }, [props.filter.type]);\n\n const baseClass = `fw-semibold mx-1 btn d-flex align-items-center`;\n const caretClass = props.hideCaret && !isDropdownFilter ? styles.hideCaret : '';\n const customWidthClass = getCustomWidthClass(props.filter);\n\n if (props.filter.type === 'button')\n return (\n <FilterComponent\n filter={props.filter}\n draftState={draftState}\n setDraftState={onSelectItem}\n />\n );\n\n return (\n <Dropdown onToggle={onToggleDropdown} show={showDropdown}>\n <Dropdown.Toggle\n id={`filterButton-${props.filter.id}`}\n className={`${baseClass} ${caretClass}`}\n variant={(currentFilterState.active && !isDropdownFilter) ? 'dark' : 'outline-dark'}\n disabled={props.filter.disabled}\n >\n {!!props.filter.icon && (\n <div className={styles.svgContainer}>\n <SvgContainer svg={props.filter.icon} />\n </div>\n )}\n {props.filter.labelPrefix} {label}\n </Dropdown.Toggle>\n\n <Dropdown.Menu>\n <div className={`mx-1 ${styles.filterMenu} ${customWidthClass} ${!isDropdownFilter ? 'px-2 py-1' : ''}`}>\n <FilterComponent\n filter={props.filter}\n draftState={draftState}\n setDraftState={onSelectItem}\n />\n\n {(!isDropdownFilter && !props.filter.disabled) && (\n <FilterActions\n active={draftState.active}\n onClickReset={onClickReset}\n onClickApply={onClickApply}\n />\n )}\n </div>\n </Dropdown.Menu>\n </Dropdown>\n );\n}\n","import { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nexport const StateHelper = {\n /**\n * Helper function to get the setState function for an individual key in a state object.\n * \n * @param setState React setState action\n * @param key Property within the state object we're updating\n * @param callback Optional callback to modify data before setting state. Uses identity fn by default.\n * \n * @returns Newly updated state object\n */\n getSetStateByKey<T extends HashObject>(\n setState: React.Dispatch<React.SetStateAction<T>>,\n key: keyof T,\n callback?: (data: any, state?: T) => T[keyof T]\n ): (data: any) => void {\n return (data: any) => setState(state => {\n const fn = FunctionHelper.isFunction(callback) ? callback : FunctionHelper.useIdentity<T>();\n return { ...state, [key]: fn(data, state) };\n });\n }\n};\n","import * as React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { FilterActions } from 'libs/shared/apps/search/components/filter-actions/FilterActions';\nimport { FilterIds, MoreFilters } from 'libs/shared/apps/search/interfaces';\nimport { DraftState, FilterContext, FilterStateHash } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { StateHelper } from 'libs/shared/utils/StateHelper';\n\nimport styles from './filter-button.module.scss';\n\nfunction getTotalActiveFilters(currentState: FilterStateHash): number {\n const total = Object.keys(currentState).reduce((acc: number, key: FilterIds) => {\n return currentState[key].active ?\n acc + 1 :\n acc;\n }, 0);\n\n return total;\n}\n\ninterface MoreFiltersButtonProps {\n filter: MoreFilters;\n}\n\nexport function MoreFiltersButton(props: MoreFiltersButtonProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n const currentFilterState = state.moreFilters;\n\n const [ label, setLabel ] = React.useState(props.filter.name);\n const [ showDropdown, setShowDropdown ] = React.useState(false);\n const [ draftState, setDraftState ] = React.useState<DraftState>(currentFilterState);\n const [ totalActiveFilters, setTotalActiveFilters ] = React.useState(getTotalActiveFilters(currentFilterState));\n\n const currentFilterStateKey = Object.keys(currentFilterState).map((id: FilterIds) => {\n return `${id}:${currentFilterState[id].active}`;\n }).join('-');\n\n React.useEffect(() => {\n setDraftState(currentFilterState);\n setTotalActiveFilters(getTotalActiveFilters(currentFilterState));\n }, [ props.filter, currentFilterStateKey ]);\n\n React.useEffect(() => {\n setLabel(totalActiveFilters ? `${props.filter.name} - ${totalActiveFilters}` : props.filter.name);\n }, [totalActiveFilters]);\n\n function onClickReset(): void {\n const filterIds = Object.keys(currentFilterState) as FilterIds[];\n\n const newState = filterIds.reduce((acc: DraftState, filterId) => {\n const filter = props.filter.filters.find(f => f.id === filterId);\n const defaultOption = filter.options?.find(o => o.default);\n\n acc[filterId] = {\n active: false,\n selection: defaultOption ? [defaultOption] : []\n };\n\n return acc;\n }, {});\n\n setDraftState(newState);\n }\n\n function onClickApply(): void {\n applyFilter();\n setShowDropdown(false);\n }\n\n function onToggleDropdown(isShowing: boolean): void {\n setShowDropdown(isShowing);\n\n if (isShowing)\n return;\n\n // Apply the filter if the dropdown has been closed\n applyFilter();\n }\n\n function applyFilter(): void {\n FilterHelper.applyFilter(\n props.filter.filters,\n currentFilterState,\n draftState,\n state.appLink\n );\n }\n\n const baseClass = `fw-semibold ${styles.hideCaret} mx-1 btn`;\n\n return (\n <Dropdown onToggle={onToggleDropdown} show={showDropdown}>\n <Dropdown.Toggle id={props.filter.id} className={baseClass} variant={totalActiveFilters ? 'dark' : 'outline-dark'}>\n {label}\n </Dropdown.Toggle>\n\n <Dropdown.Menu onClick={(e: React.MouseEvent) => e.stopPropagation()}>\n <div className={`mx-1 ${styles.moreFiltersWidth} ${props.filter.type !== 'dropdown' ? 'px-2 py-1' : ''}`}>\n {props.filter.filters.map(filter => {\n const FilterComponent = filter.customComponent ?\n filter.customComponent :\n FilterHelper.mapTypeToComponent(filter.type);\n\n return (\n <fieldset key={filter.id}>\n <FilterComponent\n filter={filter}\n draftState={draftState[filter.id]}\n setDraftState={StateHelper.getSetStateByKey(setDraftState, filter.id)}\n isOnMoreFilters\n />\n </fieldset>\n );\n })}\n\n <FilterActions\n active={!!Object.keys(draftState).find((key: FilterIds) => draftState[key].active)}\n onClickReset={onClickReset}\n onClickApply={onClickApply}\n />\n </div>\n </Dropdown.Menu>\n </Dropdown>\n );\n}\n","import React from 'react';\n\nimport styles from './tags.module.scss';\n\ninterface PartialTagItemProps {\n tagClass?: string;\n}\n\nexport const PartialTagItem = React.memo(function({ tagClass = '' }: PartialTagItemProps): JSX.Element {\n const classNames = `partial-loading-background d-inline-block rounded-pill py-1 px-2 mb-1 me-1 text-nowrap ${tagClass} ${styles.partialTag}`;\n\n return (\n <div className='mt-1'>\n <span className={classNames}>&nbsp;</span>\n </div>\n );\n});\n","import React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { DynamicWidgetState } from 'libs/shared/components/widgets/dynamic-widget';\nimport { FixedWidgetState } from 'libs/shared/components/widgets/fixed-widget';\n\n// Sync with transition time in SlidingListContainer.tsx\nconst SLIDER_ANIMATION_TIME = 400;\n\ntype FixedWidgetKeyboardOptions = {\n type: 'fixed',\n state: FixedWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery?: never\n};\n\ntype DynamicWidgetKeyboardOptions = {\n type: 'dynamic',\n state: DynamicWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery: string\n};\n\ntype UseWidgetKeyboard = FixedWidgetKeyboardOptions | DynamicWidgetKeyboardOptions;\n\nexport function useWidgetKeyboard(options: UseWidgetKeyboard) {\n const { type, state, containerRef, mediaQuery } = options;\n\n const [ isTabbing, setIsTabbing ] = React.useState(false);\n const [ dynamicAttributes, setDynamicAttributes ] = React.useState<HashObject>({});\n const [ focusedWidgetIndex, setFocusedWidgetIndex ] = React.useState(null);\n\n const isTouch = React.useMemo(() => UserAgentHelper.isTouchScreen(), []);\n\n /**\n * Get accessibility attributes for dynamic widget items\n * */\n React.useEffect(() => {\n if (type !== 'dynamic' || !containerRef.current || !(state as DynamicWidgetState).containerLeftPosition || isTouch) return;\n\n setTimeout(() => getDynamicAttributes(), SLIDER_ANIMATION_TIME + 50);\n }, [\n containerRef.current,\n mediaQuery,\n (state as DynamicWidgetState).offset,\n (state as DynamicWidgetState).containerLeftPosition\n ]);\n\n function getDynamicAttributes() {\n const dynamicWidgetState = state as DynamicWidgetState;\n\n if (!containerRef.current?.children)\n return;\n\n const focusableItems = Array.from(containerRef.current.children).reduce((acc, item) => {\n const rect = item?.getBoundingClientRect();\n\n /**\n * When any part of the widget item is visible it should be focusable,\n * otherwise prevent interaction and the slider should be the next focusable element\n * */\n const isItemVisable =\n rect.left < dynamicWidgetState.containerRightPosition &&\n rect.right > dynamicWidgetState.containerLeftPosition;\n\n return {\n ...acc,\n [item.id]: isItemVisable ?\n {\n 'aria-hidden': false\n } : {\n 'aria-hidden': true,\n 'inert': 'true'\n }\n };\n }, {});\n\n setDynamicAttributes(focusableItems);\n }\n\n /**\n * Get accessibility attributes for fixed widget items\n * */\n function getFixedAttributes(index?: number) {\n const fixedWidgetState = state as FixedWidgetState;\n\n const isItemVisible =\n isTouch ||\n index >= (fixedWidgetState.offset - fixedWidgetState.viewableItems) &&\n index < fixedWidgetState.offset;\n if (isItemVisible) {\n return {\n 'aria-hidden': false\n };\n }\n\n return {\n 'inert': 'true',\n 'aria-hidden': true\n };\n }\n\n /**\n * When the user is not signed in, there may be videos which are not focusable.\n * setTimeout is required because the transition time is 400ms\n */\n function focusNext() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let nextFocusableElement: HTMLElement = null;\n\n for (let i = (focusedWidgetIndex + 1); i < items.length; i++) {\n if (nextFocusableElement)\n break;\n\n nextFocusableElement = items[i].querySelector('a[tabindex=\"0\"]');\n }\n\n if (nextFocusableElement)\n nextFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function focusPrev() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let prevFocusableElement: HTMLElement = null;\n for (let i = focusedWidgetIndex - 1; i >= 0; i--) {\n if (prevFocusableElement) break;\n\n const item = items[i];\n prevFocusableElement = item.querySelector('a[tabindex=\"0\"]');\n }\n\n if (prevFocusableElement)\n prevFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function onFocusWidget(index: number) {\n if (document.querySelector('.user-is-tabbing')) {\n setIsTabbing(true);\n setFocusedWidgetIndex(index);\n }\n }\n\n function onBlurWidget() {\n if (!document.querySelector('.user-is-tabbing')) {\n setIsTabbing(false);\n setFocusedWidgetIndex(null);\n }\n }\n\n return {\n isTabbing,\n onFocusWidget,\n onBlurWidget,\n getFixedAttributes,\n dynamicAttributes,\n focusNext,\n focusPrev\n };\n}\n","export enum CssMeasurement {\n Percentage = '%',\n Pixels = 'px'\n}\n","import { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst blankImage = new Image();\nblankImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';\n\nexport const DragHelper = {\n // This removes the image that appears when you drag a draggable HTML element\n hideDragImage(event: React.DragEvent<HTMLElement>): void {\n if (!event.dataTransfer.setDragImage || !FunctionHelper.isFunction(event.dataTransfer.setDragImage))\n return;\n\n event.dataTransfer.setDragImage(blankImage, 0, 0);\n }\n};\n","import * as React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { CssMeasurement } from 'libs/shared/enums/CssMeasurement';\nimport { DragHelper } from 'libs/shared/utils/DragHelper';\n\nconst isTouchScreen = UserAgentHelper.isTouchScreen();\n\nconst getPositionStyling = (xPosition: number, measurement: CssMeasurement, dragPercentage?: number) => {\n // Used in situations where a touch screen user is dragging the `<FixedWidget />`\n if (measurement === CssMeasurement.Percentage && dragPercentage)\n xPosition = xPosition - dragPercentage;\n \n return {\n transform: `translate3d(${xPosition}${measurement}, 0px, 0px)`,\n // Sync with transition time in useWidgetKeyboard.ts\n transition: 'transform .4s ease-in-out'\n };\n};\n\ninterface SlidingListContainerProps extends React.PropsWithChildren<unknown> {\n position: number;\n positionType: CssMeasurement;\n\n onDrag?: (event: React.DragEvent<HTMLUListElement>) => void;\n onDragEnd?: () => void;\n\n onTouchMove?: (event: React.TouchEvent<HTMLUListElement>) => void;\n onTouchEnd?: () => void;\n\n percentageDragged?: number;\n}\n\nexport const SlidingListContainer = React.forwardRef((\n props: SlidingListContainerProps,\n ref: React.MutableRefObject<HTMLUListElement>\n): JSX.Element => {\n const { children, positionType, onDrag, onDragEnd, onTouchMove, onTouchEnd, percentageDragged, position = 0 } = props;\n\n function getEventListeners(): HashObject {\n const listenerProps: HashObject = {};\n\n if (onDrag && onDragEnd) {\n listenerProps.draggable = true;\n listenerProps.onDragEnd = onDragEnd;\n listenerProps.onDragStart = DragHelper.hideDragImage;\n listenerProps.onDragOver = onDrag;\n }\n\n if (onTouchMove && onTouchEnd && isTouchScreen) {\n listenerProps.onTouchMoveCapture = onTouchMove;\n listenerProps.onTouchEndCapture = onTouchEnd;\n }\n\n return listenerProps;\n }\n\n return (\n <ul\n className='list-unstyled d-flex flex-nowrap position-relative w-100 mb-0'\n style={getPositionStyling(position, positionType, percentageDragged)}\n ref={ref}\n {...getEventListeners()}\n >\n {children}\n </ul>\n );\n});\n","import React from 'react';\n\nexport function ChevronRightSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n d='M15.695 11.267c.407.41.407 1.056 0 1.466L9.79 18.696a1.046 1.046 0 0 1-1.474 0l-.01-.01a1.034 1.034 0 0 1 0-1.467L13.474 12l-5.17-5.22a1.034 1.034 0 0 1 0-1.465l.012-.011a1.046 1.046 0 0 1 1.474 0z'\n fill='currentColor'\n />\n </svg>\n );\n}\n",":local {\n $svg-shift: 0.1rem; // Even though the element is centered, the chevron SVGs appear slightly off-center. This corrects that.\n $title-text-height: .875rem;\n\n .buttonContainer {\n position: absolute;\n width: 100%;\n top: 0;\n pointer-events: none;\n }\n\n .left {\n left: -1rem;\n\n svg {\n transform: translateX(-$svg-shift);\n }\n }\n\n .right {\n right: -1rem;\n\n svg {\n transform: translateX($svg-shift);\n }\n }\n\n .button {\n position: absolute;\n background-color: $white;\n border-radius: $cv-svg-size-xlg * 0.5;\n cursor: pointer;\n pointer-events: auto;\n transform: translateY(-50%);\n z-index: 5;\n box-shadow: 0px 2px 4px 1px rgba(0, 0, 0, 0.3);\n height: $cv-svg-size-xlg;\n min-width: $cv-svg-size-xlg;\n display: flex;\n align-items: center;\n justify-content: center;\n\n transition: all .2s;\n\n .hoverText {\n display: none;\n transition: all .2s;\n }\n\n svg {\n color: $gray-700;\n }\n\n &:hover {\n @extend .buttonHover;\n }\n }\n\n .buttonHover {\n .hoverText ~ .chevron {\n margin-right: 0.4rem;\n }\n\n .hoverText {\n display: block;\n }\n\n svg,\n .hoverText {\n color: $gray-900;\n }\n }\n\n %backdrop {\n position: absolute;\n width: 2.5rem;\n height: 101%;\n z-index: 3;\n top: 50%;\n transform: translateY(-50%);\n }\n\n .gradientLeft {\n @extend %backdrop;\n left: -1.5rem;\n background-image: linear-gradient(to left, $cv-safe-transparent 0%, $white 70%);\n }\n\n .gradientRight {\n @extend %backdrop;\n right: -1.5rem;\n background-image: linear-gradient(to right, $cv-safe-transparent 0%, $white 70%);\n }\n\n .extendedClickableArea {\n @extend %backdrop;\n cursor: pointer;\n pointer-events: auto;\n background-color: $cv-safe-transparent;\n \n &.right {\n right: -1.5rem;\n }\n \n &.left {\n left: -1.5rem;\n }\n\n &:hover + .button {\n @extend .buttonHover\n }\n }\n\n .topPos {\n top: 50%;\n }\n}\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { FixedWidgetState } from 'libs/shared/components/widgets/fixed-widget';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { ChevronLeftSvg } from 'libs/shared/images/svg/arrows/ChevronLeftSvg';\nimport { ChevronRightSvg } from 'libs/shared/images/svg/arrows/ChevronRightSvg';\n\nimport styles from './widget-button.module.scss';\n\nconst namespace = 'shared.widgetButton';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport enum WidgetButtonDirection {\n Left,\n Right\n}\n\ninterface WidgetButtonProps {\n onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n direction: WidgetButtonDirection;\n hide: boolean;\n contents?: WidgetContents;\n useGradientBackdrop?: boolean;\n className?: string;\n hoverText?: string;\n hideExtendedClickableArea?: boolean;\n state?: FixedWidgetState;\n\n leftButtonClassName?: string;\n rightButtonClassName?: string;\n leftGradientClassName?: string;\n rightGradientClassName?: string;\n containerClassName?: string;\n}\n\nexport const WidgetButton = React.memo(function(props: WidgetButtonProps): JSX.Element {\n const isLeft = props.direction === WidgetButtonDirection.Left;\n\n const arrowSvg = isLeft ? ChevronLeftSvg : ChevronRightSvg;\n\n function getPositionClass(): string {\n let className = styles.topPos;\n \n // Left / Right\n if (isLeft)\n className += ` ${styles.left} ${props.leftButtonClassName}`;\n else\n className += ` ${styles.right} ${props.rightButtonClassName}`;\n \n return className;\n }\n\n function getStyle(): React.CSSProperties {\n if (props.state?.contents === 'videos')\n return { paddingBottom: (56.25 / props.state?.viewableItems) + '%' };\n\n return { height: '100%' };\n }\n\n if (props.hide)\n return <></>;\n\n return (\n <div className={`${styles.buttonContainer} ${props.containerClassName ? props.containerClassName : ''}`} style={getStyle()}>\n {props.useGradientBackdrop &&\n <div className={isLeft ? `${styles.gradientLeft} ${props.leftGradientClassName}` : `${styles.gradientRight} ${props.rightGradientClassName}`} />\n }\n\n {!props.hideExtendedClickableArea && (\n <button\n onClick={props.onClick}\n className={`${styles.extendedClickableArea} ${isLeft ? styles.left : styles.right}`}\n tabIndex={-1}\n />\n )}\n\n <button\n className={`${getPositionClass()} ${styles.button} ${props.className || ''}`}\n onClick={props.onClick}\n aria-label={isLeft ? getPhrase('previous') : getPhrase('next')}\n >\n {props.hoverText && (\n <span className={`ps-3 pe-2 ${styles.hoverText}`}>{props.hoverText}</span>\n )}\n <SvgContainer\n svg={arrowSvg}\n size={SvgContainerSize.Medium}\n className={`svg-container d-inline-block ${styles.chevron}`}\n />\n </button>\n </div>\n );\n});\n","export enum WidgetInteraction {\n Init = 'init',\n Next = 'next',\n Previous = 'previous',\n Resize = 'resize',\n Drag = 'drag',\n Update = 'update',\n JumpToIndex = 'jump-to-index'\n}\n","import * as React from 'react';\n\n/**\n * Hook function for listening to scroll events\n * @param onResize - gets called on resize.\n * @param onResizeEnd (optional) - gets called 100ms after the last resize event. Timer restarts everytime the callback\n * runs so that endCallback only fires after a stretch of resize events.\n * @param dependencies - values from the component (e.g. state, props and functions) that are used \n * inside the effect hook.\n */\nexport function useResizeListener(onResize: () => void, onResizeEnd?: () => void, dependencies: any[] = []): void {\n let resizeTimeout: number;\n\n const onResizeModified = () => {\n onResize();\n\n window.clearTimeout(resizeTimeout);\n resizeTimeout = window.setTimeout(onResizeEnd, 100);\n };\n\n React.useEffect(() => {\n window.addEventListener('resize', onResizeEnd ? onResizeModified : onResize);\n return () => window.removeEventListener('resize', onResizeEnd ? onResizeModified : onResize);\n }, [...dependencies]);\n}\n","import { ReducerActions } from 'libs/common/react/interfaces';\n\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { WidgetInteraction } from 'libs/shared/enums/WidgetInteraction';\nimport { SlidingListRefs } from 'libs/shared/interfaces/SlidingListRefs';\n\nimport { DynamicWidgetState } from './DynamicWidgetReducer';\n\ninterface WidgetSnapshot extends DynamicWidgetState {\n initialMouseX: number;\n}\n\n/**\n * Resize events\n */\nexport const getResizeHandler = (\n elementRefs: SlidingListRefs,\n dispatch: React.Dispatch<ReducerActions<WidgetInteraction>>,\n mediaQuery: MediaQueryStrings\n) => () => {\n if (elementRefs.container.current)\n elementRefs.container.current.style.transition = '';\n\n dispatch({\n type: WidgetInteraction.Resize,\n payload: {\n elementRefs,\n mediaQuery\n }\n });\n};\n\nexport const getResizeEndHandler = (containerRef: React.MutableRefObject<HTMLUListElement>) => () => {\n if (containerRef.current)\n containerRef.current.style.transition = 'transform .4s ease-in-out';\n};\n\nexport const getDragHandler = (\n containerRef: React.MutableRefObject<HTMLUListElement>,\n widgetState: DynamicWidgetState,\n dispatch: React.Dispatch<ReducerActions<WidgetInteraction>>,\n widgetSnapshot: WidgetSnapshot,\n setWidgetSnapshot: React.Dispatch<WidgetSnapshot>\n) => (event: React.DragEvent<HTMLUListElement>): void => {\n const mouseX = event.clientX;\n\n let snapshot = widgetSnapshot;\n\n if (!snapshot) {\n snapshot = { ...widgetState, initialMouseX: mouseX };\n setWidgetSnapshot(snapshot);\n containerRef.current.style.transition = '';\n }\n\n dispatch({\n type: WidgetInteraction.Drag,\n payload: {\n widgetSnapshot: snapshot,\n currentMouseX: mouseX\n }\n });\n};\n\nexport const getDragEndHandler = (\n containerRef: React.MutableRefObject<HTMLUListElement>,\n setWidgetSnapshot: React.Dispatch<WidgetSnapshot>\n) => () => {\n containerRef.current.style.transition = 'transform .4s ease-in-out';\n setWidgetSnapshot(null);\n};\n","import { ReducerActions } from 'libs/common/react/interfaces';\n\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { WidgetInteraction } from 'libs/shared/enums/WidgetInteraction';\nimport { SlidingListRefs } from 'libs/shared/interfaces/SlidingListRefs';\n\nexport interface DynamicWidgetState {\n /**\n * X-position argument for `translate3d()` to determine where the slider is positioned.\n */\n offset: number;\n\n /**\n * Left position of the slider container.\n * Set on `Init`, and updated on `Resize`.\n * Used for calculations on `Previous`, or for dragging to the right.\n */\n containerLeftPosition: number;\n\n /**\n * Right position of the slider container.\n * Set on Init, and updated on Resize.\n * Used for calculations on `Next`, or for dragging to the left.\n */\n containerRightPosition: number;\n\n /**\n * The position of the left edge of the very first element in the slider list.\n * Initially this will always be equal to `containerLeftPosition`.\n */\n firstElementPosition: number;\n\n /**\n * The position of the right edge of the very last element in the slider list.\n */\n lastElementPosition: number;\n\n /**\n * True when `firstElementPosition === containerLeftPosition`.\n */\n hideLeftButton: boolean;\n\n /**\n * True when `lastElementPositon === containerRightPosition`.\n */\n hideRightButton: boolean;\n\n /**\n * When clicking left or right, this number is the max distance in pixels that the slider.\n * will move.\n * Default 300.\n * Can only be set once on `Init` action.\n */\n maxSlideDistance: number;\n\n /**\n * This is calculated on `Init`, and is the lowest number the `offset` state can ever be.\n * This is needed for the `Drag` event, as the `Drag` event can only calculate whole numbers.\n * 99% of the time, the leftOffsetLimit is a very specific decimal number, so we calculate it\n * on `Init` and reference it on `Drag` events when necessary.\n */\n leftOffsetLimit: number;\n}\n\nfunction getMaxSlideDistance(mediaQuery: MediaQueryStrings): number {\n if (mediaQuery === MediaQueryStrings.XS)\n return 200;\n\n if (mediaQuery === MediaQueryStrings.SM || mediaQuery === MediaQueryStrings.MD)\n return 350;\n\n return 500;\n}\n\n/**\n * `null` values are initialized in the `Init` action. This is dispatched\n * later, because it uses JQuery elements that aren't immediately available\n * when `useReducer` is called.\n */\nexport const initialSliderState: DynamicWidgetState = {\n offset: 0,\n containerLeftPosition: null,\n containerRightPosition: null,\n firstElementPosition: null,\n lastElementPosition: null,\n hideLeftButton: true,\n hideRightButton: true,\n maxSlideDistance: 0,\n leftOffsetLimit: null\n};\n\ninterface InitPayload {\n elementRefs: SlidingListRefs;\n mediaQuery: MediaQueryStrings;\n}\n\nconst onInit = (payload: InitPayload): DynamicWidgetState => {\n const { container, lastElement } = payload.elementRefs;\n\n if (!container?.current || !lastElement?.current)\n return initialSliderState;\n\n const containerRect = container.current.getBoundingClientRect();\n const containerLeftPosition = containerRect.left;\n const containerRightPosition = containerRect.right;\n\n const firstElementPosition = containerLeftPosition;\n const lastElementPosition = lastElement.current.getBoundingClientRect().right;\n const leftOffsetLimit = containerRightPosition - lastElementPosition;\n\n return {\n ...initialSliderState,\n containerLeftPosition,\n containerRightPosition,\n firstElementPosition,\n lastElementPosition,\n hideRightButton: lastElementPosition < containerRightPosition,\n leftOffsetLimit,\n maxSlideDistance: getMaxSlideDistance(payload.mediaQuery)\n };\n};\n\ninterface ResizePayload {\n elementRefs: SlidingListRefs;\n mediaQuery: MediaQueryStrings;\n}\n\nconst onResize = (payload: ResizePayload): DynamicWidgetState => {\n const initialState = onInit({\n ...payload,\n ...payload.elementRefs\n });\n\n return {\n ...initialState,\n maxSlideDistance: getMaxSlideDistance(payload.mediaQuery)\n };\n};\n\nconst onNext = (prevState: DynamicWidgetState): Partial<DynamicWidgetState> => {\n const { firstElementPosition, lastElementPosition, maxSlideDistance, offset, containerRightPosition } = prevState;\n\n /**\n * The distance in pixels that the slider will move along the x-axis.\n * This will be the `maxSlideDistance` constant value, or if that value is too large we calculate\n * the remaining overflowing space and only slide by that amount.\n */\n const slideDistance = lastElementPosition - containerRightPosition >= maxSlideDistance ?\n maxSlideDistance :\n lastElementPosition - containerRightPosition;\n\n return {\n firstElementPosition: firstElementPosition - slideDistance,\n lastElementPosition: lastElementPosition - slideDistance,\n offset: offset - slideDistance,\n hideRightButton: lastElementPosition - slideDistance === containerRightPosition,\n hideLeftButton: false\n };\n};\n\nconst onPrevious = (prevState: DynamicWidgetState): Partial<DynamicWidgetState> => {\n const { containerLeftPosition, firstElementPosition, lastElementPosition, maxSlideDistance, offset } = prevState;\n\n const fullSlide = firstElementPosition + maxSlideDistance <= containerLeftPosition;\n const slideDistance = fullSlide ? maxSlideDistance : Math.abs(offset);\n\n return {\n firstElementPosition: firstElementPosition + slideDistance,\n lastElementPosition: lastElementPosition + slideDistance,\n offset: offset + slideDistance,\n hideLeftButton: !fullSlide || firstElementPosition + slideDistance === containerLeftPosition,\n hideRightButton: false\n };\n};\n\nconst onDrag = (prevState: DynamicWidgetState, payload: any): Partial<DynamicWidgetState> => {\n const { widgetSnapshot, currentMouseX } = payload;\n\n // Disable dragging if the slider isn't long enough\n if (widgetSnapshot.hideLeftButton && widgetSnapshot.hideRightButton)\n return {};\n\n // The distance from the initial `MouseDown` event x-coordinate, to the present x-coordinate\n const dragDistance = widgetSnapshot.initialMouseX - currentMouseX;\n\n let offset = widgetSnapshot.offset - dragDistance;\n let firstElementPosition = widgetSnapshot.firstElementPosition - dragDistance;\n let lastElementPosition = widgetSnapshot.lastElementPosition - dragDistance;\n let hideLeftButton = false;\n let hideRightButton = false;\n\n if (firstElementPosition > prevState.containerLeftPosition) {\n offset = 0;\n firstElementPosition = prevState.containerLeftPosition;\n lastElementPosition = prevState.lastElementPosition;\n hideLeftButton = true;\n }\n\n if (lastElementPosition <= prevState.containerRightPosition) {\n offset = prevState.leftOffsetLimit;\n firstElementPosition = prevState.containerLeftPosition - Math.abs(prevState.leftOffsetLimit);\n lastElementPosition = widgetSnapshot.containerRightPosition;\n hideRightButton = true;\n }\n\n return {\n offset,\n firstElementPosition,\n lastElementPosition,\n hideLeftButton,\n hideRightButton\n };\n};\n\nexport function DynamicWidgetReducer(\n prevState: DynamicWidgetState,\n action: ReducerActions<WidgetInteraction>\n): DynamicWidgetState {\n switch (action.type) {\n case WidgetInteraction.Init:\n return {\n ...prevState,\n ...onInit(action.payload)\n };\n\n case WidgetInteraction.Resize:\n return {\n ...prevState,\n ...onResize(action.payload)\n };\n\n case WidgetInteraction.Next:\n return {\n ...prevState,\n ...onNext(prevState)\n };\n\n case WidgetInteraction.Previous:\n return {\n ...prevState,\n ...onPrevious(prevState)\n };\n\n case WidgetInteraction.Drag:\n return {\n ...prevState,\n ...onDrag(prevState, action.payload)\n };\n\n default:\n return prevState;\n }\n}\n",":local {\n .itemSpacing {\n &:not(:last-child) {\n margin-right: map-get($spacers, 2);\n }\n }\n\n .header {\n z-index: 1;\n position: relative;\n }\n\n .mobileScroll {\n overflow-x: scroll;\n -ms-overflow-style: none;\n scrollbar-width: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n }\n\n .leftGradient {\n left: -2rem;\n }\n\n .leftGradientNoPadding {\n left: 0;\n }\n\n .leftButton {\n left: -1.3rem;\n }\n\n .leftButtonNoPadding {\n left: 0.1rem;\n }\n\n .rightGradient {\n right: -2rem;\n }\n\n .rightGradientNoPadding {\n right: 0;\n }\n\n .rightButton {\n right: -1.3rem;\n }\n\n .rightButtonNoPadding {\n right: 0.5rem;\n }\n}","import * as React from 'react';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { Core } from 'libs/common/core';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { WidgetHeader } from 'libs/shared/components/widgets/curated-widgets/components/header/WidgetHeader';\nimport { useWidgetKeyboard } from 'libs/shared/components/widgets/hooks/useWidgetKeyboard';\nimport { SlidingListContainer } from 'libs/shared/components/widgets/sliding-list/SlidingListContainer';\nimport { WidgetButton, WidgetButtonDirection } from 'libs/shared/components/widgets/widget-button/WidgetButton';\nimport { CssMeasurement } from 'libs/shared/enums/CssMeasurement';\nimport { WidgetInteraction } from 'libs/shared/enums/WidgetInteraction';\nimport { useGetMediaQueryString } from 'libs/shared/hooks/UseGetMediaQueryString';\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\nimport { BaseObject } from 'libs/shared/interfaces';\nimport { SlidingListRefs } from 'libs/shared/interfaces/SlidingListRefs';\nimport { PartialLoadingHelper, PartialLoadingOptions } from 'libs/shared/utils/PartialLoadingHelper';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { getDragEndHandler, getDragHandler, getResizeEndHandler, getResizeHandler } from './DynamicWidgetEventHandlers';\nimport { DynamicWidgetReducer, DynamicWidgetState, initialSliderState } from './DynamicWidgetReducer';\n\nimport styles from './dynamic-widget.module.scss';\n\ninterface WidgetSnapshot extends DynamicWidgetState {\n initialMouseX: number;\n}\n\ninterface StaticChild {\n position: 'start' | 'end';\n component: React.ElementType;\n}\n\ninterface DynamicWidgetProps {\n id?: string;\n childComponent: React.ElementType;\n childComponentProps?: any;\n partialLoadingComponent: React.ElementType;\n partialLoadingOptions?: PartialLoadingOptions;\n\n widgetDataDeps?: (any)[];\n getChildAppLink?: (data: any) => Core.AppLink;\n\n staticChildren?: StaticChild[];\n collection?: BaseObject[];\n fetch?: (...args: any[]) => any;\n lazyLoad?: boolean;\n\n heading?: string;\n headingAppLink?: Core.AppLink;\n description?: string;\n getSubtitle?: (data: any) => string;\n\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n\n getWidgetItemAnalyticsData?: (data: any) => HashObject;\n hideButtons?: boolean;\n childClassName?: string;\n // set to true if the widget get cut off by the container\n noNegativePadding?: boolean;\n}\n\nDynamicWidget.defaultProps = {\n heading: '',\n description: '',\n childComponentProps: {}\n};\n\nexport function DynamicWidget(props: DynamicWidgetProps): JSX.Element {\n const { childComponent: WidgetItemComponent, staticChildren, getWidgetItemAnalyticsData = () => {} } = props;\n\n const [ state, dispatch ] = React.useReducer(DynamicWidgetReducer, initialSliderState);\n\n // A snapshot of the widget state is captured on the very first `Drag` event as a point of reference\n const [ widgetSnapshot, setWidgetSnapshot ] = React.useState<WidgetSnapshot>(null);\n\n const elementRefs: SlidingListRefs = {\n container: React.useRef(null),\n firstElement: React.useRef(null),\n lastElement: React.useRef(null)\n };\n\n const mediaQuery = useGetMediaQueryString();\n const isTouchScreen = UserAgentHelper.isTabletOrMobile();\n \n const { dynamicAttributes, focusNext, focusPrev, onFocusWidget, onBlurWidget } = useWidgetKeyboard({ type: 'dynamic', state, containerRef: elementRefs.container, mediaQuery });\n\n useResizeListener(\n getResizeHandler(elementRefs, dispatch, mediaQuery),\n getResizeEndHandler(elementRefs.container),\n [mediaQuery]\n );\n\n const { ref, inView } = useLazyLoad({ prevent: !props.lazyLoad });\n\n let widgetData = props.collection;\n\n if (!props.collection && FunctionHelper.isFunction(props.fetch)) {\n const request = props.fetch(inView);\n widgetData = request.data;\n }\n\n /**\n * Once the widget data has been set, we can initialize the reducer. This is because\n * the reducer depends on the refs being set, but they don't get set until the markup has been loaded.\n */\n React.useEffect(() => {\n if (!widgetData || ObjectHelper.isEmpty(widgetData))\n return;\n\n dispatch({\n type: WidgetInteraction.Init,\n payload: {\n elementRefs,\n mediaQuery\n }\n });\n }, [widgetData]);\n\n function getWidgetItems(): JSX.Element {\n if (!widgetData)\n return;\n\n const firstChildren = staticChildren?.filter(child => child.position === 'start') ?? [];\n const lastChildren = staticChildren?.filter(child => child.position === 'end') ?? [];\n\n let items = widgetData.map((widgetItem, index) => {\n let itemRef: React.MutableRefObject<HTMLLIElement>;\n\n if (widgetItem === ArrayHelper.first(widgetData) && firstChildren?.length)\n itemRef = elementRefs.firstElement;\n\n if (widgetItem === ArrayHelper.last(widgetData) && !lastChildren?.length)\n itemRef = elementRefs.lastElement;\n\n const isLast = index + 1 === widgetData.length;\n\n return (\n <li\n id={widgetItem.id}\n key={widgetItem.id}\n ref={itemRef}\n onFocus={() => onFocusWidget(index)}\n onBlur={() => onBlurWidget()}\n className={`${styles.itemSpacing} ${props.childClassName || ''} ${(isLast && isTouchScreen) ? 'pe-4' : ''}`}\n {...dynamicAttributes[widgetItem.id]}\n >\n <WidgetItemComponent\n getChildAppLink={props.getChildAppLink}\n data={widgetItem}\n getSubtitle={props.getSubtitle}\n analyticsData={{\n itemIndex: index,\n ...props.analyticsData,\n ...getWidgetItemAnalyticsData(widgetItem)\n }}\n analyticsOptions={{ ...props?.analyticsOptions, ...WidgetHelper.getSliderItemAnalyticsOptions() }}\n {...props.childComponentProps}\n />\n </li>\n );\n });\n\n if (firstChildren.length) {\n items = [\n ...firstChildren.map((child, i) => {\n const Component = child.component;\n\n return (\n <li\n key={`first-widget-component:${i}`}\n ref={i === 0 ? elementRefs.firstElement : null}\n className={`${styles.itemSpacing} ${props.childClassName || ''}`}\n >\n <Component />\n </li>\n );\n }),\n ...items\n ];\n }\n\n if (lastChildren.length) {\n items = [\n ...items,\n ...lastChildren.map((child, i) => {\n const Component = child.component;\n\n return (\n <li\n key={`end-widget-component:${i}`}\n ref={i === lastChildren.length - 1 ? elementRefs.lastElement : null}\n className={`${styles.itemSpacing} ${props.childClassName || ''}`}\n >\n <Component />\n </li>\n );\n })\n ];\n }\n\n return <>{items}</>;\n }\n const widgetItems = React.useMemo(getWidgetItems, [\n widgetData, dynamicAttributes, state.offset, mediaQuery, ...props.widgetDataDeps || []\n ]);\n\n if (widgetData && !widgetData.length && !staticChildren?.length)\n return <></>;\n\n if (!widgetData || ObjectHelper.isEmpty(widgetData)) {\n return (\n <div ref={ref}>\n <PartialDynamicWidget\n partialLoadingComponent={props.partialLoadingComponent}\n partialLoadingOptions={props.partialLoadingOptions}\n />\n </div>\n );\n }\n\n const getSliderAnalyticsData = (type: WidgetInteraction) => ({\n ...props.analyticsData,\n id: props.id,\n name: props.heading,\n direction: type === WidgetInteraction.Next ? 'right' : 'left'\n });\n\n const hideButtons = isTouchScreen || props.hideButtons;\n\n return (\n <div className={`${props.noNegativePadding ? '' : 'mx-n4'}`}>\n <div className={`px-4 ${styles.header}`}>\n <WidgetHeader\n name={props.heading}\n description={props.description}\n appLink={props.headingAppLink}\n showSeeMoreLink={!!props.headingAppLink}\n />\n </div>\n\n <div className='position-relative'>\n <div className={`${props.noNegativePadding ? '' : 'px-4' } py-3 my-n3 position-relative ${isTouchScreen ? styles.mobileScroll : 'overflow-hidden-x'}`}>\n <div className={`position-relative ${props.hideButtons ? 'overflow-hidden-x' : ''}`}>\n {!hideButtons && (\n <WidgetButton\n direction={WidgetButtonDirection.Left}\n onClick={() => {\n focusPrev();\n\n dispatch({ type: WidgetInteraction.Previous });\n AnalyticsHelper.logUserAction(\n getSliderAnalyticsData(WidgetInteraction.Previous),\n WidgetHelper.getSliderAnalyticsOptions()\n );\n }}\n leftButtonClassName={`${styles.leftButton} ${props.noNegativePadding ? styles.leftButtonNoPadding : ''}`}\n leftGradientClassName={`${styles.leftGradient} ${props.noNegativePadding ? styles.leftGradientNoPadding : ''}`}\n hide={state.hideLeftButton}\n useGradientBackdrop\n />\n )}\n\n <SlidingListContainer\n position={state.offset}\n positionType={CssMeasurement.Pixels}\n onDrag={getDragHandler(elementRefs.container, state, dispatch, widgetSnapshot, setWidgetSnapshot)}\n onDragEnd={getDragEndHandler(elementRefs.container, setWidgetSnapshot)}\n ref={elementRefs.container}\n >\n {widgetItems}\n </SlidingListContainer>\n\n {!hideButtons && (\n <WidgetButton\n direction={WidgetButtonDirection.Right}\n onClick={() => {\n focusNext();\n\n dispatch({ type: WidgetInteraction.Next });\n AnalyticsHelper.logUserAction(\n getSliderAnalyticsData(WidgetInteraction.Next),\n WidgetHelper.getSliderAnalyticsOptions()\n );\n }}\n hide={state.hideRightButton}\n rightButtonClassName={`${styles.rightButton} ${props.noNegativePadding ? styles.rightButtonNoPadding : ''}`}\n rightGradientClassName={`${styles.rightGradient} ${props.noNegativePadding ? styles.rightGradientNoPadding : ''}`}\n useGradientBackdrop\n />\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\ntype PartialDynamicWidgetProps = Pick<DynamicWidgetProps, 'partialLoadingComponent'> & {\n partialLoadingOptions?: PartialLoadingOptions\n};\n\nexport const PartialDynamicWidget = (props: PartialDynamicWidgetProps) => {\n const { partialLoadingComponent: Component, partialLoadingOptions } = props;\n\n return (\n <div className='d-flex flex-nowrap overflow-hidden'>\n {PartialLoadingHelper.getPartialLoadingItems(partialLoadingOptions).map((item, idx) => <Component key={idx} />)}\n </div>\n );\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { FilterOption } from 'libs/shared/apps/search/interfaces';\nimport { TagItem } from 'libs/shared/components/tags/TagItem';\nimport { BaseObject, Tag } from 'libs/shared/interfaces';\n\nexport interface TagWidgetItemProps {\n appLink: Core.AppLink;\n data: Tag;\n selectedItems?: BaseObject[];\n onClick?: (data: Tag | FilterOption) => void;\n}\n\nexport function TagWidgetItem(props: TagWidgetItemProps): JSX.Element {\n const isSelected = props.selectedItems.find(selection => selection.id === props.data.id);\n\n const colorClass = isSelected ? `bg-gray-900 text-white` : 'bg-light';\n\n return (\n <TagItem\n tag={props.data}\n appLink={props.appLink}\n tagClass={`no-decoration ${colorClass} lh-1`}\n onClick={() => props.onClick(props.data)}\n />\n );\n}\n",":local {\n .tagItem {\n // Default tag styles\n line-height: 1rem;\n }\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterState } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { PartialTagItem } from 'libs/shared/components/tags/PartialTagItem';\nimport { DynamicWidget } from 'libs/shared/components/widgets/dynamic-widget/DynamicWidget';\nimport { TagWidgetItem, TagWidgetItemProps } from 'libs/shared/components/widgets/items/tag-widget-item/TagWidgetItem';\n\nimport styles from './tag-filter.module.scss';\n\ninterface TagFilterProps {\n filter: SearchFilter;\n queryParams: HashObject;\n isFetching?: boolean;\n}\n\nexport function TagFilter(props: TagFilterProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n\n if (!props.filter?.id)\n return <></>;\n\n const currentFilterState = state[props.filter.id];\n\n const { selection: selections } = currentFilterState;\n\n const unappliedOptions = props.filter?.options?.filter(opt => {\n return !selections?.find(selection => selection.id === opt.id);\n }) ?? [];\n\n function onClickOption(option: FilterOption): void {\n let nextFilterState: FilterState = null;\n\n let indexOfItem: number = -1;\n\n // Find the index of the selected item if it's already selected\n selections.find((selection, i) => {\n if (indexOfItem > -1)\n return;\n\n if (selection.id.toString() !== option.id.toString())\n return;\n\n indexOfItem = i;\n });\n\n if (indexOfItem >= 0) {\n const newItems = [ ...selections.slice(0, indexOfItem), ...selections.slice(indexOfItem + 1) ];\n \n nextFilterState = {\n active: !!newItems.length,\n selection: newItems\n };\n } else {\n nextFilterState = {\n active: true,\n selection: selections.concat(option)\n };\n }\n\n FilterHelper.applyFilter(\n [props.filter],\n currentFilterState,\n { [props.filter.id]: nextFilterState },\n state.appLink\n );\n }\n\n function getContainerClass(): string {\n let className = 'mb-3';\n\n if (collection.length && props.isFetching)\n className += ' mt-n1';\n else if (!collection.length && !props.isFetching)\n className += ' d-none';\n\n return className;\n }\n\n const collection = [ ...selections, ...(props.isFetching ? [] : unappliedOptions) ];\n\n return (\n <div className={(props.isFetching || collection.length) ? 'py-2' : ''}>\n <div className={getContainerClass()}>\n {(!!collection.length || props.isFetching) && (\n <DynamicWidget\n collection={collection}\n childComponent={(props: TagWidgetItemProps) => (\n <TagWidgetItem\n {...props}\n selectedItems={selections}\n onClick={onClickOption}\n />\n )}\n staticChildren={props.isFetching ?\n new Array(3).fill({\n component: () => <PartialTagItem tagClass={styles.tagItem} />,\n position: 'end'\n }) :\n []\n }\n partialLoadingComponent={() => (\n <div className='me-2'>\n <PartialTagItem tagClass={`${styles.tagItem}`} />\n </div>\n )}\n />\n )}\n </div>\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { MoreFilters, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext } from 'libs/shared/apps/search/reducers';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PropsWithAnalyticsOptions } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM } from '../../utils/SharedSearchHelper';\n\ntype ResetButtonProps = PropsWithAnalyticsOptions<{\n currentQueryParam: string,\n mainFilters: Array<SearchFilter>,\n moreFilters: MoreFilters,\n alignLeft?: boolean\n}>;\n\nexport function ResetButton(props: ResetButtonProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n\n const onClickReset = () => {\n const currentParams = (ContextService.getCurrentRoute().appLink?.params ?? {}) as HashObject;\n const savedParams = ObjectHelper.pick(currentParams, [ 'query', SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM ]);\n\n Core.AppLinkHelper.trigger({\n ...state.appLink,\n params: savedParams\n });\n };\n\n return (\n <DivButton\n onClick={onClickReset}\n className={`${props.alignLeft ? 'order-first' : ''} hover-text-underline cursor-pointer d-flex align-items-center mx-2`}\n >\n <Text namespace='search.resetButton' phrase='reset' />\n </DivButton>\n );\n}\n",":local {\n .partialFilterHeading {\n height: 1.5rem;\n width: 3.5rem;\n }\n\n .partialButton {\n height: 2.2rem;\n width: 5rem;\n }\n\n .filtersContainer {\n row-gap: map-get($spacers, 1);\n }\n}","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsOptions } from 'libs/analytics/interfaces';\n\nimport { FilterButton } from 'libs/shared/apps/search/components/filter-button/FilterButton';\nimport { MoreFiltersButton } from 'libs/shared/apps/search/components/filter-button/MoreFiltersButton';\nimport { TagFilter } from 'libs/shared/apps/search/components/filter-types/tag-filter/TagFilter';\nimport { ResetButton } from 'libs/shared/apps/search/components/reset-button/ResetButton';\nimport { MoreFilters, SearchFilter, SearchIndices } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterReducer } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nimport styles from './search-filters.module.scss';\n\ntype SearchFiltersProps = {\n queryParams: HashObject,\n mainFilters: SearchFilter[],\n appLink: Core.AppLink,\n moreFilters?: MoreFilters,\n isFetchingOptions?: boolean,\n constantIndices?: SearchIndices[],\n analyticsOptions?: AnalyticsOptions,\n\n hideHeading?: boolean,\n hideDivider?: boolean,\n hideResetButton?: boolean,\n alignResetButtonLeft?: boolean,\n hideCaret?: boolean,\n\n /**\n * Incremental changes flag for new search\n */\n _hasNewSearch?: boolean,\n /**\n * Incremental changes flag for partner profiles\n */\n _hasPartnerProfiles?: boolean\n};\n\nexport function SearchFilters(props: SearchFiltersProps): JSX.Element {\n const { queryParams, appLink, hideHeading, isFetchingOptions, constantIndices = []} = props;\n\n const newState = React.useMemo(() => {\n return FilterHelper.deriveInitialStateFromQuery(queryParams, props.mainFilters, props.moreFilters, appLink);\n }, [ queryParams, isFetchingOptions ]);\n\n const [ state, dispatch ] = React.useReducer(FilterReducer, newState);\n\n React.useEffect(() => {\n if (ObjectHelper.isEqual(newState, state))\n return;\n\n dispatch({\n type: 'update',\n payload: newState\n });\n\n if (props.analyticsOptions) {\n FilterHelper.logFilterEvent(\n props.mainFilters,\n props.moreFilters,\n newState,\n queryParams.query,\n props.analyticsOptions\n );\n }\n }, [newState]);\n\n const indices = ArrayHelper.uniq([\n ...FilterHelper.getAppliedIndices(queryParams, props._hasNewSearch, props._hasPartnerProfiles),\n ...constantIndices\n ]);\n\n const { mainFilters, moreFilters } = FilterHelper.mixinDisabledFields(\n state,\n indices,\n props.mainFilters,\n props.moreFilters\n );\n\n // Separate the tag filter as it's rendered differently\n const mainFiltersWithoutTags = mainFilters.filter(f => f.type !== 'tag');\n const tagFilter = mainFilters.find(f => f.type === 'tag');\n\n return (\n <FilterContext.Provider value={{ state, dispatch }}>\n <LanguageNamespaceContext.Provider value='search.searchFilters'>\n <section>\n <div className={classNames(\n 'd-flex',\n !props.hideDivider && 'border-bottom pb-3 mb-3',\n (props._hasNewSearch && props.hideDivider && 'pb-3'),\n (props._hasNewSearch && !props.hideDivider && 'border-gray-300')\n )}>\n {!hideHeading && (\n <h2 className='h5 mb-0 d-inline-block pe-2 border-end d-flex align-items-center'>\n <Text phrase='heading' />\n </h2>\n )}\n\n <div className={classNames(`d-flex flex-wrap ${styles.filtersContainer}`, !hideHeading && 'ms-2')}>\n {mainFiltersWithoutTags.map(f => (\n <FilterButton key={f.id} filter={f} hideCaret={props.hideCaret} />\n ))}\n\n {moreFilters && <MoreFiltersButton filter={moreFilters} />}\n\n {FilterHelper.hasActiveFilters(queryParams) && !props.hideResetButton && (\n <ResetButton\n mainFilters={props.mainFilters}\n moreFilters={props.moreFilters}\n currentQueryParam={queryParams.query}\n analyticsOptions={props.analyticsOptions}\n alignLeft={props.alignResetButtonLeft}\n />\n )}\n </div>\n </div>\n \n <TagFilter\n filter={tagFilter}\n queryParams={queryParams}\n isFetching={props.isFetchingOptions}\n />\n </section>\n </LanguageNamespaceContext.Provider>\n </FilterContext.Provider>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BhOZYAZn.chunk.js","names":[],"sources":["../../../../libs/shared/src/interfaces/models/CalendarEvent.ts","../../../../libs/shared/src/constants/TopicsConstants.ts","../../../../libs/shared/src/apps/search/components/filter-actions/FilterActions.tsx","../../../../libs/shared/src/apps/search/reducers/FilterReducer.tsx","../../../../libs/shared/src/apps/search/components/filter-dropdown-title/FilterDropdownTitle.tsx","../../../../libs/shared/src/apps/search/components/filter-types/checkbox-filter/CheckboxFilterList.tsx","../../../../libs/shared/src/apps/search/components/filter-types/checkbox-filter/CheckboxFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/nested-checkbox-filter/components/NestedFilterOptions.tsx","../../../../libs/shared/src/apps/search/components/filter-types/nested-checkbox-filter/components/SecondLayerOptions.tsx","../../../../libs/shared/src/apps/search/components/filter-types/nested-checkbox-filter/NestedCheckboxFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/switch-filter/SwitchFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/dropdown-filter/DropdownFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/radio-filter/radio-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/radio-filter/RadioFilter.tsx","../../../../libs/shared/src/components/rating-range-selector/RatingRangeSelector.tsx","../../../../libs/shared/src/apps/search/components/filter-types/rating-filter/rating-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/rating-filter/RatingFilter.tsx","../../../../libs/shared/src/apps/search/constants/FilterConstants.ts","../../../../libs/shared/src/apps/search/utils/SourceFilterHelper.ts","../../../../libs/shared/src/enums/CurationTag.ts","../../../../libs/shared/src/enums/CustomerStatus.ts","../../../../libs/shared/src/apps/calendar/constants/SpecialEventTypeLabelMap.ts","../../../../libs/shared/src/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/activation-action-info/BulkUserActivationActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/activation-email-info/BulkUserActivationEmailActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/add-to-classroom-action-info/BulkAddToClassroomActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/change-year-group-action-info/ChangeYearGroupActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/delete-action-info/BulkUserDeleteActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/remove-action-info/BulkUserRemoveActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/reset-email-info/BulkUserResetEmailActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/reset-password-action-info/BulkResetPasswordActionInfo.tsx","../../../../libs/shared/src/apps/user-manager/components/bulk-actions-wizard/select-action/year-group-rollover-action-info/BulkUserYearGroupRolloverActionInfo.tsx","../../../../libs/shared/src/images/svg/status/CheckCircleSvg.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/user-item-components.module.scss","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/UserStatusBadge.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/BasicUserDetails.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/RoleOrYearGroup.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/components/UserItemAvatar.tsx","../../../../libs/shared/src/apps/user-manager/components/user-list-items/bulk-user-actions-errored-user-item/BulkUserActionsErroredUserItem.tsx","../../../../libs/shared/src/apps/user-manager/enums/UserManagerClient.ts","../../../../libs/shared/src/context/WizardLayoutContext.tsx","../../../../libs/shared/src/enums/BatchDataType.ts","../../../../libs/shared/src/enums/BatchJobName.ts","../../../../libs/shared/src/enums/BatchJobResultErrorCode.ts","../../../../libs/shared/src/enums/BatchJobType.ts","../../../../libs/shared/src/images/svg/objects/KeySvg.tsx","../../../../libs/shared/src/apps/user-manager/utils/BulkUserActionsHelper.tsx","../../../../libs/shared/src/apps/search/components/filter-types/custom/duration-filter/DurationFilter.tsx","../../../../libs/shared/src/constants/XmasConstants.ts","../../../../libs/shared/src/apps/search/components/filter-types/custom/movies-and-tv-filter/movies-and-tv-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/custom/movies-and-tv-filter/MoviesAndTvFilter.tsx","../../../../libs/shared/src/apps/search/components/filter-types/grouped-checkbox-filter/GroupedCheckboxFilter.tsx","../../../../libs/shared/src/apps/search/utils/ClassificationFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/DurationFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/PresentationFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/ProductionYearFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/RatingFilterHelper.ts","../../../../libs/shared/src/apps/search/utils/FilterHelper.tsx","../../../../libs/shared/src/apps/search/components/filter-button/filter-button.module.scss","../../../../libs/shared/src/apps/search/components/filter-button/FilterButton.tsx","../../../../libs/shared/src/utils/StateHelper.ts","../../../../libs/shared/src/apps/search/components/filter-button/MoreFiltersButton.tsx","../../../../libs/shared/src/components/tags/PartialTagItem.tsx","../../../../libs/shared/src/components/widgets/hooks/useWidgetKeyboard.ts","../../../../libs/shared/src/enums/CssMeasurement.ts","../../../../libs/shared/src/utils/DragHelper.ts","../../../../libs/shared/src/components/widgets/sliding-list/SlidingListContainer.tsx","../../../../libs/shared/src/images/svg/arrows/ChevronRightSvg.tsx","../../../../libs/shared/src/components/widgets/widget-button/widget-button.module.scss","../../../../libs/shared/src/components/widgets/widget-button/WidgetButton.tsx","../../../../libs/shared/src/enums/WidgetInteraction.ts","../../../../libs/shared/src/hooks/UseResizeListener.ts","../../../../libs/shared/src/components/widgets/dynamic-widget/DynamicWidgetEventHandlers.ts","../../../../libs/shared/src/components/widgets/dynamic-widget/DynamicWidgetReducer.tsx","../../../../libs/shared/src/components/widgets/dynamic-widget/dynamic-widget.module.scss","../../../../libs/shared/src/components/widgets/dynamic-widget/DynamicWidget.tsx","../../../../libs/shared/src/components/widgets/items/tag-widget-item/TagWidgetItem.tsx","../../../../libs/shared/src/apps/search/components/filter-types/tag-filter/tag-filter.module.scss","../../../../libs/shared/src/apps/search/components/filter-types/tag-filter/TagFilter.tsx","../../../../libs/shared/src/apps/search/components/reset-button/ResetButton.tsx","../../../../libs/shared/src/apps/search/components/search-filters/search-filters.module.scss","../../../../libs/shared/src/apps/search/components/search-filters/SearchFilters.tsx"],"sourcesContent":["import { BaseObject, BasePaginatedCollection, Classification, Livestream } from 'libs/shared/interfaces';\n\nexport type CalendarEventType = 'Observance' | 'ReligiousEvent' | 'Holiday' | 'Livestream';\n\nexport enum SpecialEventType {\n Holiday = 'Holiday',\n SportingEvent = 'SportingEvent',\n Observance = 'Observance',\n NaturalDisaster = 'NaturalDisaster',\n HistoricalEvent = 'HistoricalEvent',\n BreakingNews = 'BreakingNews',\n Informal = 'Informal',\n ReligiousEvent = 'ReligiousEvent',\n Livestream = 'Livestream',\n Other = 'Other'\n}\n\nexport enum CalendarEventContentType {\n Classification,\n Livestream\n}\n\nexport enum CalendarEventFrequency {\n Regular = 'Regular',\n Daily = 'Daily',\n Weekly = 'Weekly',\n Monthly = 'Monthly',\n Yearly = 'Yearly'\n}\n\nexport enum CalendarEventStatus {\n Draft = 'Draft',\n Published = 'Published',\n Archived = 'Archived'\n}\n\nexport type CalendarEventContent = Classification | Livestream;\n\nexport interface CalendarEvent<T extends CalendarEventContent = Classification> {\n id: string;\n type: CalendarEventType;\n name: string;\n description?: string;\n startDate: string;\n endDate?: string;\n content: T;\n specialEventId?: string;\n specialEventPolicyId?: string;\n metadata?: {\n objectType: 'Topic' | 'Livestream',\n objectId: string\n };\n}\n\nexport interface SpecialEvent<T extends CalendarEventContent = Classification> {\n id: string;\n name: string;\n description: string;\n policies: SpecialEventPolicy<T>[];\n status: CalendarEventStatus;\n type: SpecialEventType;\n}\n\nexport type SpecialEventCollection<T extends CalendarEventContent = Classification> =\n BasePaginatedCollection<SpecialEvent<T>>;\n\nexport interface SpecialEventPolicy<T extends CalendarEventContent = Classification> extends BaseObject {\n content: T;\n specialEventId: string;\n status: CalendarEventStatus;\n presentationId: string;\n startDate: string;\n endDate: string;\n frequency: CalendarEventFrequency;\n interval: number;\n visible: boolean;\n metadata: {\n objectId: string,\n objectType: 'Topic' | 'Livestream'\n };\n}\n","export const TopicsConstants = {\n MULTI_PRESENTATION_THRESHOLD: 2\n};\n","import * as React from 'react';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'search.filterActions';\n\ninterface FilterActionsProps {\n className?: string;\n onClickReset: () => void;\n onClickApply: () => void;\n active: boolean;\n}\n\nFilterActions.defaultProps = {\n active: false,\n className: ''\n};\n\nexport function FilterActions(props: FilterActionsProps): JSX.Element {\n return (\n <div className={`d-flex justify-content-between ${props.className}`}>\n {props.active ? (\n <DivButton className='text-secondary hover-text-underline cursor-pointer' onClick={props.onClickReset}>\n <Text namespace={namespace} phrase='reset' />\n </DivButton>\n ) : (\n <div className='invisible' />\n )}\n\n <DivButton className='info-link' onClick={props.onClickApply}>\n <Text namespace={namespace} phrase='apply' />\n </DivButton>\n </div>\n );\n}\n","import { createContext } from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { ReducerActions } from 'libs/common/react/interfaces';\n\nimport { FilterIds, FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\n\nexport type FilterState = {\n active: boolean,\n selection?: FilterOption[]\n};\n\nexport type DraftState = {\n [key in FilterIds]?: FilterState;\n};\n\ntype FilterStateHashFilters = {\n [key in FilterIds]: FilterState;\n};\n\nexport type FilterStateHash = FilterStateHashFilters & {\n appLink: Core.AppLink,\n moreFilters?: Omit<FilterStateHash, 'moreFilters'>\n};\n\nexport type FilterActionType = 'update';\n\nexport type FilterPayloadType = {\n filter: SearchFilter,\n state: FilterState\n};\n\n/**\n * Context\n */\ninterface FilterContextType {\n state: FilterStateHash;\n dispatch: React.Dispatch<ReducerActions<FilterActionType>>;\n}\n\nexport const FilterContext = createContext<FilterContextType>(null);\n\n/**\n * Reducer - root level keys should match the filter object's corresponding \"id\" field\n */\nexport function FilterReducer(\n state: FilterStateHash,\n action: ReducerActions<FilterActionType, FilterStateHash>\n): FilterStateHash {\n switch (action.type) {\n case 'update': {\n return action.payload;\n }\n\n default:\n return state;\n }\n}\n","import React from 'react';\n\ninterface FilterDropdownTitleProps {\n id?: string;\n title: string;\n}\n\nexport function FilterDropdownTitle(props: FilterDropdownTitleProps): JSX.Element {\n return (\n <label htmlFor={props.id} className='mb-0'>\n <h3 className='h6 mb-2'>{props.title}</h3>\n </label>\n );\n}\n","import React from 'react';\n\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\n\nimport { FilterOption, MoreFilters, SearchFilter } from '../../../interfaces';\nimport { FilterState } from '../../../reducers';\n\ninterface CheckboxFilterListProps {\n displayOptionsIn2Columns: boolean;\n filter: SearchFilter | MoreFilters;\n draftState: FilterState;\n setDraftState: (state: FilterState) => void;\n options: FilterOption[];\n}\n\nexport function CheckboxFilterList(props: CheckboxFilterListProps): JSX.Element {\n const selections = props.draftState.selection;\n\n function onToggleItem(option: FilterOption, isCurrentlyChecked: boolean): void {\n /**\n * If the item is currently checked, we remove it from the array\n */\n if (isCurrentlyChecked) {\n let indexOfItem: number = -1;\n\n // Find the index of the clicked item\n selections.find((selection, i) => {\n if (indexOfItem > -1)\n return;\n\n if (selection.id.toString() !== option.id.toString())\n return;\n\n indexOfItem = i;\n });\n\n // Return a new array with the clicked item sliced out\n const newItems = [ ...selections.slice(0, indexOfItem), ...selections.slice(indexOfItem + 1) ];\n\n props.setDraftState({ active: !!newItems.length, selection: newItems });\n\n return;\n }\n\n /**\n * If the item wasn't checked, simply push it onto the selections array\n */\n const newItems = [...selections];\n newItems.push(option);\n\n props.setDraftState({\n active: !!newItems.length,\n selection: newItems\n });\n }\n\n const options = props.options.map(option => {\n const isDisabled = props.filter.disabled || option.disabled;\n const isChecked = !!props.draftState.selection.find(s => s.id.toString() === option.id.toString());\n const joinedIds = Array.isArray(option.id) ? option.id.join('_') : option.id;\n \n return (\n <li key={joinedIds} className={`my-1 ${props.displayOptionsIn2Columns ? 'col-md-6 col-12' : ''}`}>\n <Checkbox\n label={option.name}\n name={joinedIds}\n id={joinedIds}\n onChange={() => onToggleItem(option, isChecked)}\n checked={!isDisabled && isChecked}\n isLabelEllipsis={props.displayOptionsIn2Columns}\n disabled={isDisabled}\n />\n </li>\n );\n });\n \n return <ul className={`list-unstyled ${props.displayOptionsIn2Columns ? 'd-flex flex-wrap' : ''}`}>{options}</ul>;\n}\n","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\n\nimport { CheckboxFilterList } from './CheckboxFilterList';\n\nexport function CheckboxFilter(props: FilterProps): JSX.Element {\n const displayOptionsIn2Columns = FilterHelper.displayTwoColumns(props.filter);\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n\n <Form className='mb-3'>\n <CheckboxFilterList\n displayOptionsIn2Columns={displayOptionsIn2Columns}\n options={props.filter.options}\n filter={props.filter}\n draftState={props.draftState}\n setDraftState={props.setDraftState}\n />\n </Form>\n </>\n );\n}\n","import * as React from 'react';\n\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\n\ntype NestedFilterOptionsProps = FilterProps & {\n onToggleItem: (selectedOption: FilterOption, isCurrentlyCheckedOrIndeterminate: boolean) => void,\n onToggleChildItem: (selectedOption: FilterOption, isCurrentlyChecked: boolean, parentOption: FilterOption) => void\n};\n\nexport function NestedFilterOptions(props: NestedFilterOptionsProps): JSX.Element {\n const allOptions: JSX.Element[] = [];\n\n for (const firstLayerOption of props.filter.options) {\n const isFirstLayerOptionDisabled = props.filter.disabled || firstLayerOption.disabled;\n const currentSelection = props.draftState.selection?.find(s => s?.id === firstLayerOption.id);\n const secondLayerOptions = firstLayerOption.secondLayerOptions ?? [];\n const isFirstLayerIndeterminate = getIsFirstLayerIndeterminate(currentSelection, secondLayerOptions);\n const isFirstLayerOptionChecked = !isFirstLayerIndeterminate && !!currentSelection;\n\n // 1st layer\n allOptions.push(\n <Checkbox\n key={firstLayerOption.id}\n label={firstLayerOption.name}\n name={firstLayerOption.id}\n id={firstLayerOption.id}\n indeterminate={isFirstLayerIndeterminate}\n onChange={() => props.onToggleItem(firstLayerOption, isFirstLayerOptionChecked || isFirstLayerIndeterminate)}\n checked={ !isFirstLayerOptionDisabled && isFirstLayerOptionChecked}\n className='my-1'\n disabled={isFirstLayerOptionDisabled}\n />\n );\n\n // 2nd layer\n const showSecondLayer = FilterHelper.hasManyFilterOptions(secondLayerOptions);\n\n showSecondLayer && allOptions.push(\n ...secondLayerOptions.map(secondLayerOption => {\n const isSecondLayerOptionDisabled = isFirstLayerOptionDisabled || secondLayerOption.disabled;\n const isSecondLayerOptionChecked = !!currentSelection?.secondLayerSelection\n ?.find(s => s.id === secondLayerOption.id);\n\n return (\n <Checkbox\n key={secondLayerOption.id}\n label={secondLayerOption.name}\n name={secondLayerOption.id}\n id={secondLayerOption.id}\n onChange={() => props.onToggleChildItem(secondLayerOption, isSecondLayerOptionChecked, firstLayerOption)}\n checked={!isSecondLayerOptionDisabled && isSecondLayerOptionChecked}\n className='my-1 ms-3'\n disabled={isSecondLayerOptionDisabled}\n />\n );\n })\n );\n }\n\n return <>{allOptions}</>;\n}\n\nfunction getIsFirstLayerIndeterminate(currentSelection: FilterOption, secondLayerOptions: FilterOption[]): boolean {\n const hasSecondLayerSelection = currentSelection?.secondLayerSelection?.length > 0;\n const allSecondLayerOptionsChecked = currentSelection?.secondLayerSelection?.length === secondLayerOptions.length;\n return hasSecondLayerSelection && !allSecondLayerOptionsChecked;\n}\n","import * as React from 'react';\n\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { Checkbox } from 'libs/shared/components/forms/form-checkbox/Checkbox';\n\ntype SecondLayerOptionProps = FilterProps & {\n onToggleChildItem: (selectedOption: FilterOption, isCurrentlyChecked: boolean, parentOption: FilterOption) => void\n};\n\nexport function SecondLayerOptions(props: SecondLayerOptionProps): JSX.Element {\n for (const firstLayerOption of props.filter.options) {\n const isFirstLayerOptionDisabled = props.filter.disabled || firstLayerOption.disabled;\n const currentSelection = props.draftState.selection?.find(s => s?.id === firstLayerOption.id);\n const secondLayerOptions = firstLayerOption.secondLayerOptions ?? [];\n\n const options = secondLayerOptions.map(secondLayerOption => {\n const isSecondLayerOptionDisabled = isFirstLayerOptionDisabled || secondLayerOption.disabled;\n const isSecondLayerOptionChecked = !!currentSelection?.secondLayerSelection\n ?.find(s => s.id === secondLayerOption.id);\n\n return (\n <Checkbox\n key={secondLayerOption.id}\n label={secondLayerOption.name}\n name={secondLayerOption.id}\n id={secondLayerOption.id}\n onChange={() => props.onToggleChildItem(secondLayerOption, isSecondLayerOptionChecked, firstLayerOption)}\n checked={!isSecondLayerOptionDisabled && isSecondLayerOptionChecked}\n className='my-1'\n disabled={isSecondLayerOptionDisabled}\n />\n );\n });\n\n return <>{options}</>;\n }\n}\n","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\n\nimport { NestedFilterOptions } from './components/NestedFilterOptions';\nimport { SecondLayerOptions } from './components/SecondLayerOptions';\n\nexport function NestedCheckboxFilter(props: FilterProps): JSX.Element {\n const options = props.filter.options;\n\n function onToggleItem(selectedOption: FilterOption, isCurrentlyCheckedOrIndeterminate: boolean): void {\n const { selection } = props.draftState;\n const indexOfOption = selection.findIndex(o => o.id === selectedOption.id);\n\n /**\n * If the item wasn't checked, simply push it onto the selections array\n */\n if (!isCurrentlyCheckedOrIndeterminate) {\n const enabled2ndLayerOptions = (options\n ?.find(o => o.id === selectedOption.id).secondLayerOptions)\n ?.filter(o => !o.disabled);\n\n // Also select all enabled 2nd layer options\n const newSelectedOptionWith2ndLayerOptions =\n { ...selectedOption, secondLayerSelection: enabled2ndLayerOptions };\n\n // Add new option\n if (selection.length === 0 || indexOfOption === -1) {\n const newSelection = [ ...selection, newSelectedOptionWith2ndLayerOptions ];\n\n props.setDraftState({\n active: true,\n selection: newSelection\n });\n\n return;\n }\n\n // Merge selectedItem into selection\n if (indexOfOption !== -1) {\n const newSelection = selection.map(firstLayer => {\n if (firstLayer.id === selectedOption.id) {\n return newSelectedOptionWith2ndLayerOptions;\n }\n\n return firstLayer;\n });\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n\n return;\n }\n }\n\n /**\n * If the item is currently checked, we remove it from the array\n */\n const newSelection = ArrayHelper.removeItemFromIndex(\n selection,\n selection.findIndex(selectionItem => selectionItem.id === selectedOption.id)\n );\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n }\n\n function onToggleChildItem(\n selectedOption: FilterOption,\n isCurrentlyChecked: boolean,\n parentOption: FilterOption\n ): void {\n const { selection } = props.draftState;\n const indexOfParentOption = selection.findIndex(o => o.id === parentOption.id);\n\n if (!isCurrentlyChecked) {\n const newChildSelection = [ ...selection[indexOfParentOption]?.secondLayerSelection ?? [], selectedOption ];\n\n // If no selection/new item is not in selection, add new option\n if (selection.length === 0 || indexOfParentOption === -1) {\n const newParentSelection = {\n ...parentOption,\n secondLayerSelection: newChildSelection\n };\n\n const newSelection = [ ...selection, newParentSelection ];\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n\n return;\n }\n\n // Merge selectedItem into selection\n if (indexOfParentOption !== -1) {\n const newSelection = selection.map(firstLayer => {\n if (firstLayer.id === parentOption.id) {\n return {\n ...firstLayer,\n secondLayerSelection: newChildSelection\n };\n }\n\n return firstLayer;\n });\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n\n return;\n }\n }\n\n // Uncheck child\n let newSelection = selection.map(firstLayer => {\n if (firstLayer.id === parentOption.id) {\n const new2ndLayerSelection = ArrayHelper.removeItem(firstLayer.secondLayerSelection, selectedOption);\n return { ...parentOption, secondLayerSelection: new2ndLayerSelection };\n }\n\n return firstLayer;\n });\n\n // Uncheck parent if no child\n if (newSelection[indexOfParentOption].secondLayerSelection.length === 0) {\n newSelection = ArrayHelper.removeItem(newSelection, parentOption);\n }\n\n props.setDraftState({\n active: !!newSelection.length,\n selection: newSelection\n });\n }\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n <Form className='mb-3'>\n { FilterHelper.hasManyFilterOptions(options) ?\n <NestedFilterOptions onToggleItem={onToggleItem} onToggleChildItem={onToggleChildItem} {...props} /> :\n <SecondLayerOptions onToggleChildItem={onToggleChildItem} {...props} />\n }\n </Form>\n </>\n );\n}\n","import * as React from 'react';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { ToggleSwitch } from 'libs/shared/components/toggle-switch/ToggleSwitch';\n\nexport function SwitchFilter(props: FilterProps): JSX.Element {\n const isActive = props.draftState.active;\n\n function onToggle(): void {\n props.setDraftState({ active: !isActive });\n }\n\n return (\n <>\n <FilterDropdownTitle id={props.filter.id} title={props.filter.name} />\n\n <div className='d-flex align-items-start justify-content-between'>\n <p className='d-inline-block w-75'>{props.filter.description}</p>\n\n <ToggleSwitch id={props.filter.id} disabled={props.filter.disabled} onClick={onToggle} on={isActive} />\n </div>\n </>\n );\n}\n","import React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nexport function DropdownFilter(props: FilterProps): JSX.Element {\n function onSelect(option: FilterOption): void {\n props.setDraftState({\n active: !option.default,\n selection: [option]\n });\n }\n\n return (\n <>\n {props.filter.options.map(option => (\n <Dropdown.Item\n key={option.id}\n onClick={() => onSelect(option)}\n disabled={props.filter.disabled || option.disabled}\n >\n {option.name}\n </Dropdown.Item>\n ))}\n </>\n );\n}\n",":local {\n .radioFilter {\n margin: map-get($spacers, 1) 0;\n\n label::after {\n cursor: pointer;\n }\n }\n}","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nimport styles from './radio-filter.module.scss';\n\nexport function RadioFilter(props: FilterProps): JSX.Element {\n function onSelect(option: FilterOption): void {\n props.setDraftState({\n active: !option.default,\n selection: [option]\n });\n }\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n\n <Form>\n <ul className={`${props.isOnMoreFilters ? 'd-flex flex-wrap' : ''} list-unstyled`}>\n {props.filter.options.map(option => {\n const isDisabled = props.filter.disabled || option.disabled;\n const isSelected = ArrayHelper.first(props.draftState.selection)?.id.toString() === option.id.toString();\n return (\n <li key={option.id} className={`${props.isOnMoreFilters ? 'w-50' : ''}`}>\n <Form.Check\n type='radio'\n label={option.name}\n name={option.id}\n id={option.id}\n value={option.id}\n onChange={() => onSelect(option)}\n checked={!isDisabled && isSelected}\n className={`${styles.radioFilter}`}\n disabled={isDisabled}\n />\n </li>\n );\n })}\n </ul>\n </Form>\n </>\n );\n}\n","import React from 'react';\nimport { ButtonGroup } from 'react-bootstrap';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { useHover } from 'libs/shared/hooks/UseHover';\nimport { Rating, YearGroup } from 'libs/shared/interfaces';\n\ninterface RatingButtonProps {\n rating: Rating;\n isActive: boolean;\n onClick: () => void;\n onHover: (rating: Rating) => void;\n getButtonClasses: (rating: Rating, isActive: boolean, isHovering: boolean) => string;\n disabled?: boolean;\n}\n\nfunction RatingButton(props: RatingButtonProps): JSX.Element {\n const [ ref, isHovering ] = useHover<HTMLDivElement>({ delay: 1 });\n\n React.useEffect(() => {\n props.onHover(isHovering ? props.rating : null);\n }, [isHovering]);\n\n if (!props.rating.code)\n return <></>;\n\n const button = (\n <DivButton\n ref={ref}\n className={props.getButtonClasses(props.rating, props.isActive, isHovering)}\n onClick={props.onClick}\n disabled={props.disabled}\n >\n {props.rating.code}\n </DivButton>\n );\n\n if (props.disabled)\n return button;\n\n return (\n <Tooltip title={props.rating.name} spanHack>\n {button}\n </Tooltip>\n );\n}\n\ninterface RatingRangeSelectorProps {\n ratings: Rating[];\n yearGroup?: YearGroup;\n yearGroups?: YearGroup[];\n selections: Rating[];\n onSelectRange: (range: Rating[]) => void;\n getButtonClasses: (rating: Rating, isActive: boolean, isHovering: boolean) => string;\n isDisabled?: (rating: Rating) => boolean;\n disabled?: boolean;\n}\n\nRatingRangeSelector.defaultProps = {\n selections: []\n};\n\nexport function RatingRangeSelector(props: RatingRangeSelectorProps): JSX.Element {\n const [ hoverRange, setHoverRange ] = React.useState<Rating[]>([]);\n\n function getRange(rating: Rating): Rating[] {\n return props.ratings.filter(r => r.code && r.value <= rating.value);\n }\n\n function onClickRating(rating: Rating): void {\n props.onSelectRange(getRange(rating));\n }\n\n function onHover(rating: Rating): void {\n if (!rating || props.isDisabled(rating)) {\n setHoverRange([]);\n return;\n }\n }\n\n function isActive(rating: Rating): boolean {\n if (hoverRange.length)\n return !!hoverRange.find(r => r.id === rating.id);\n\n return !!props.selections.find(r => r.id === rating.id);\n }\n\n return (\n <div>\n <ButtonGroup as='ul' className='list-unstyled mb-0'>\n {props.ratings.map(rating => (\n <li key={rating.id}>\n <RatingButton\n rating={rating}\n onClick={() => onClickRating(rating)}\n onHover={onHover}\n isActive={isActive(rating)}\n disabled={props.disabled || props.isDisabled?.(rating)}\n getButtonClasses={props.getButtonClasses}\n />\n </li>\n ))}\n </ButtonGroup>\n </div>\n );\n}\n",":local {\n .firstButton {\n border-radius: 0;\n border-top-left-radius: $border-radius;\n border-bottom-left-radius: $border-radius;\n }\n\n .lastButton {\n border-radius: 0;\n border-top-right-radius: $border-radius;\n border-bottom-right-radius: $border-radius;\n }\n}\n","import * as React from 'react';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\nimport { RatingRangeSelector } from 'libs/shared/components/rating-range-selector/RatingRangeSelector';\nimport { Rating } from 'libs/shared/interfaces';\n\nimport styles from './rating-filter.module.scss';\n\ntype OptionType = FilterOption & Rating;\n\nexport function RatingFilter(props: FilterProps): JSX.Element {\n const options = props.filter.options as OptionType[];\n\n function onSelectRange(range: OptionType[]): void {\n props.setDraftState({\n active: !!range.length,\n selection: range as FilterOption[]\n });\n }\n\n const filteredRatings: Rating[] = options.filter(r => r.code);\n const [firstRating] = filteredRatings;\n const lastRating = filteredRatings[filteredRatings.length - 1];\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n <p>{props.filter.description}</p>\n\n <div className='mb-2'>\n <RatingRangeSelector\n ratings={options}\n selections={props.draftState.selection as Rating[]}\n onSelectRange={onSelectRange}\n disabled={props.filter.disabled}\n isDisabled={(rating: Rating & FilterOption) => rating.disabled}\n getButtonClasses={(rating, isActive, isHovering) => {\n let className = 'btn border text-nowrap';\n\n if (isActive || isHovering)\n className += ' btn-dark';\n else\n className += ' btn-outline-dark';\n\n if (isHovering)\n className += ' active';\n\n if (filteredRatings.length === 1)\n className += ' rounded';\n else if (firstRating.id === rating.id)\n className += ' ' + styles.firstButton;\n else if (lastRating.id === rating.id)\n className += ' ' + styles.lastButton;\n else\n className += ' rounded-0';\n\n return className;\n }}\n />\n </div>\n </>\n );\n}\n","export const FilterConstants = {\n FILTER_PARAM_PREFIX: 'filters.',\n MAX_CHECKBOXES_PER_COLUMN: 10\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { FilterConstants } from 'libs/shared/apps/search/constants/FilterConstants';\nimport { FilterOption, SourceFilterOptions } from 'libs/shared/apps/search/interfaces';\nimport { MasterObjectTypes } from 'libs/shared/enums/MasterObjectTypes';\nimport { Library } from 'libs/shared/interfaces';\n\nconst namespace = 'sharedSearch.utils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst LIBRARY_FILTER = `${FilterConstants.FILTER_PARAM_PREFIX}library`;\n\nfunction getTypeMap(libraries: Library[]): HashObject {\n return libraries.reduce<HashObject>((prev, next) => {\n return {\n ...prev,\n [next.type]: true\n };\n }, {});\n}\n\nexport const SourceFilterHelper = {\n getOptions(opts: {\n libraries: Library[],\n isLearner: boolean,\n isGuest: boolean,\n hasCustomLibraries: boolean,\n liveStreams?: boolean\n }): FilterOption<SourceFilterOptions>[] {\n const { libraries, isLearner, isGuest, hasCustomLibraries, liveStreams } = opts;\n\n const options: FilterOption<SourceFilterOptions>[] = [];\n\n const libraryTypes = getTypeMap(libraries);\n\n if (libraryTypes[MasterObjectTypes.Workspace] && !isGuest)\n options.push({ id: SourceFilterOptions.MyVideos, name: getPhrase('myVideos') });\n\n if (libraryTypes[MasterObjectTypes.CustomLibrary] && (!isLearner || hasCustomLibraries))\n options.push({ id: SourceFilterOptions.School, name: getPhrase('schoolVideos') });\n\n if (libraryTypes[MasterObjectTypes.Exchange])\n options.push({ id: SourceFilterOptions.ExchangeArchive, name: getPhrase('exchangeArchiveVideos') });\n\n if (libraryTypes[MasterObjectTypes.HostedLibrary])\n options.push({ id: SourceFilterOptions.ClickView, name: getPhrase('clickViewVideos') });\n\n if (libraryTypes[MasterObjectTypes.HostedLibrary] && liveStreams)\n options.push({ id: SourceFilterOptions.LiveStreams, name: getPhrase('livestreams') });\n\n return options;\n },\n\n getBackendParamValue(\n val: SourceFilterOptions | SourceFilterOptions[],\n libraries: Library[],\n streamableLibraryId: string\n ): HashObject {\n const values = Array.isArray(val) ? val : [val];\n\n return values.reduce((acc, value) => {\n return libraries.reduce((prev, next) => {\n const libraryIds = prev[LIBRARY_FILTER] || [];\n\n if (value === SourceFilterOptions.MyVideos && next.type === MasterObjectTypes.Workspace)\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n \n if (value === SourceFilterOptions.School && next.type === MasterObjectTypes.CustomLibrary)\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n\n if (value === SourceFilterOptions.ExchangeArchive && next.type === MasterObjectTypes.Exchange)\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n \n if (\n value === SourceFilterOptions.ClickView &&\n next.type === MasterObjectTypes.HostedLibrary &&\n next.id.toString() !== streamableLibraryId\n )\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n\n if (value === SourceFilterOptions.LiveStreams &&\n next.type === MasterObjectTypes.HostedLibrary &&\n next.id.toString() === streamableLibraryId\n )\n return { ...prev, [LIBRARY_FILTER]: [ ...libraryIds, next.id.toString() ]};\n \n return prev;\n }, acc);\n }, {} as HashObject);\n }\n};\n","export enum CurationTag {\n CLICKVIEW_CURATED = 'is_clickview_curated',\n MOVIES_AND_TV = 'is_movies_and_tv',\n STREAMABLE_CURATED = 'is_streamable_learning_curated'\n}\n","export enum CustomerStatus {\n Unclassified = 0,\n Active = 1,\n Prospect = 2,\n LostCustomer = 3,\n Disabled = 4,\n Other = 5\n}\n\nexport enum CustomerStatusString {\n Unclassified = 'Unclassified',\n Active = 'Active',\n Prospect = 'Prospect',\n LostCustomer = 'LostCustomer',\n Disabled = 'Disabled',\n Other = 'Other'\n}\n","import { SpecialEventType } from 'libs/shared/interfaces';\n\nexport const SpecialEventTypeLabelMap: Record<SpecialEventType, string> = {\n [SpecialEventType.BreakingNews]: 'Breaking news',\n [SpecialEventType.HistoricalEvent]: 'Historical event',\n [SpecialEventType.Holiday]: 'Holiday',\n [SpecialEventType.Informal]: 'Informal',\n [SpecialEventType.Livestream]: 'Livestream',\n [SpecialEventType.NaturalDisaster]: 'Natural disaster',\n [SpecialEventType.Observance]: 'Observance',\n [SpecialEventType.ReligiousEvent]: 'Religious event',\n [SpecialEventType.SportingEvent]: 'Sporting event',\n \n [SpecialEventType.Other]: 'Other'\n};\n","import React from 'react';\n\nexport function WizardActionInfoContainer(props: React.PropsWithChildren<any>): JSX.Element {\n return (\n <div className='alert text-dark bg-light-blue px-2 rounded-3'>\n {props.children}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\n\nconst namespace = 'userManager.bulkUserActivationActionInfo';\n\ninterface BulkUserActivationActionInfoProps {\n userType: UserGroup;\n}\n\nexport function BulkUserActivationActionInfo(props: BulkUserActivationActionInfoProps): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='deactivate' /></h4>\n <p>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'deactivateInfoStudent' : 'deactivateInfoStaff'} />\n </p>\n\n <h4 className='h5'><Text namespace={namespace} phrase='reactivate' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'reactivateInfoStudent' : 'reactivateInfoStaff'} />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkUserActivationEmailActionInfo';\n\nexport function BulkUserActivationEmailActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.addToClassroomActionInfo';\n\nexport function BulkAddToClassroomActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.changeYearGroupActionInfo';\n\nexport function BulkChangeYearGroupActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\n\nconst namespace = 'userManager.bulkUserDeleteActionInfo';\n\ninterface BulkUserDeleteActionInfoProps {\n userType: UserGroup;\n}\n\nexport function BulkUserDeleteActionInfo(props: BulkUserDeleteActionInfoProps): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='delete' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'infoStudent' : 'infoStaff'} />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\n\nconst namespace = 'userManager.bulkUserRemoveActionInfo';\n\ninterface BulkUserRemoveActionInfoProps {\n userType: UserGroup;\n}\n\nexport function BulkUserRemoveActionInfo(props: BulkUserRemoveActionInfoProps): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='remove' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase={props.userType === UserGroup.Learner ? 'infoStudent' : 'infoStaff'} />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkUserResetEmailActionInfo';\n\nexport function BulkUserResetEmailActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkResetPasswordActionInfo';\n\nexport function BulkResetPasswordActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { WizardActionInfoContainer } from 'libs/shared/components/wizard/select-action/wizard-action-info-container/WizardActionInfoContainer';\n\nconst namespace = 'userManager.bulkUserYearGroupRolloverActionInfo';\n\nexport function BulkUserYearGroupRolloverActionInfo(): JSX.Element {\n return (\n <WizardActionInfoContainer>\n <h4 className='h5'><Text namespace={namespace} phrase='heading' /></h4>\n <p className='mb-0'>\n <Text namespace={namespace} phrase='info' />\n </p>\n </WizardActionInfoContainer>\n );\n}\n","import React from 'react';\n\nexport function CheckCircleSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M12 3c4.972 0 9 4.028 9 9s-4.028 9-9 9-9-4.028-9-9 4.028-9 9-9m4.244 5.578a.77.77 0 0 0-1.058.068l-4.722 5.18-1.684-1.615a.77.77 0 0 0-1.06 0 .7.7 0 0 0 0 1.018l2.25 2.16a.77.77 0 0 0 1.094-.035l5.25-5.76a.7.7 0 0 0-.07-1.016'\n />\n </svg>\n );\n}\n",":local {\n .badge {\n border-radius: 3px;\n font-size: 0.8rem;\n\n &.pending {\n background-color: $gray-700;\n }\n\n &.active {\n background-color: $green-500;\n }\n }\n\n .name {\n max-width: 75%;\n }\n\n .username {\n max-width: 70%;\n }\n\n .lastActiveContainer {\n width: 5rem;\n\n &.isCurrentUser {\n width: 6.8rem; // Current user won't have the \"more action\" dropdown, so this needs to be slightly wider.\n }\n }\n\n .pillContainer {\n width: 6.25rem;\n }\n\n .avatarContainer {\n width: $cv-user-options-avatar-size;\n min-width: $cv-user-options-avatar-size;\n height: $cv-user-options-avatar-size;\n }\n\n .verifiedEmail {\n margin-right: 0.1rem;\n }\n\n .authMethodContainer {\n width: 6rem;\n }\n\n .authMethodLogo {\n @extend .avatarContainer;\n\n background-size: contain;\n margin-right: -10%;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { ObjectStatus } from 'libs/shared/enums/ObjectStatus';\nimport { CurrentUser, User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './user-item-components.module.scss';\n\nconst namespace = 'userManager.userList';\n\ninterface UserStatusBadgeProps {\n user?: Partial<User>;\n status?: ObjectStatus;\n currentUser?: CurrentUser;\n className?: string;\n showActiveBadge?: boolean;\n}\n\nexport function UserStatusBadge(props: UserStatusBadgeProps): JSX.Element {\n return (\n <>\n {/* \"Deactivated\" badge */}\n {(UserHelper.getUserStatusFromValue(props.user?.status ?? props.status) === ObjectStatus.Disabled) && (\n <div className={`text-white px-1 ${styles.badge} bg-danger ${props.className ?? ''}`}>\n <Text namespace={namespace} phrase='deactivated' />\n </div>\n )}\n\n {/* \"Pending badge\" */}\n {(UserHelper.getUserStatusFromValue(props.user?.status ?? props.status) === ObjectStatus.Inactive) && (\n <div className={`text-white px-1 ${styles.badge} ${styles.pending} ${props.className ?? ''}`}>\n <Tooltip title={LanguageService.getPhrase(namespace, 'pendingTooltip')} spanHack>\n <Text namespace={namespace} phrase='pending' />\n </Tooltip>\n </div>\n )}\n\n {/* \"Active badge\" */}\n {props.showActiveBadge &&\n (UserHelper.getUserStatusFromValue(props.user?.status ?? props.status) === ObjectStatus.Active)\n && (\n <div className={`text-white px-1 ${styles.badge} ${styles.active} ${props.className ?? ''}`}>\n <Tooltip title={LanguageService.getPhrase(namespace, 'active')} spanHack>\n <Text namespace={namespace} phrase='active' />\n </Tooltip>\n </div>\n )}\n\n {/* \"That's me\" badge */}\n {props.user?.id.toString() === props.currentUser?.id.toString() && (\n <div className={`text-white px-1 ${styles.badge} bg-blue ${props.className ?? ''}`}>\n <Text namespace={namespace} phrase='thatsYou' />\n </div>\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { CheckCircleSvg } from 'libs/shared/images/svg/status/CheckCircleSvg';\nimport { CurrentUser, User } from 'libs/shared/interfaces';\n\nimport { UserStatusBadge } from './UserStatusBadge';\n\nimport styles from './user-item-components.module.scss';\n\nconst namespace = 'userManager.userList';\n\ninterface BasicUserDetailsProps {\n user: Partial<User>;\n currentUser?: CurrentUser;\n wrapperClassName?: string;\n}\n\nexport function BasicUserDetails(props: BasicUserDetailsProps): JSX.Element {\n const { user, currentUser } = props;\n\n return (\n <div className={`d-flex flex-column justify-content-center me-auto w-100 ${props.wrapperClassName}`}>\n <div className='pb-1 d-flex align-items-center'>\n {/* Name, username, and status */}\n <div className={`d-flex ${styles.name}`}>\n {user.name ? (\n <h2\n className='h5 m-0 me-1 d-inline-block align-middle text-truncate'\n title={`${user.name} ${user.surname || ''}`}\n >\n {user.name} {user.surname || ''}\n </h2>\n ) : (\n <span className='fst-italic text-secondary me-2'>\n <Text namespace={namespace} phrase='noName' />\n </span>\n )}\n {user.username && (\n <>\n (\n <p title={user.username} className={`m-0 d-inline-block align-middle text-truncate ${styles.username}`}>\n {user.username}\n </p>\n )\n </>\n )}\n </div>\n\n <UserStatusBadge user={user} currentUser={currentUser} className='ms-2' />\n </div>\n\n {/* Email and verification status */}\n <div className='d-flex'>\n {!!user.metadata?.isEmailVerified && (\n <SvgContainer\n className={`svg-container text-secondary ms-n1 ${styles.verifiedEmail}`}\n svg={CheckCircleSvg}\n title={LanguageService.getPhrase(namespace, 'emailVerified')}\n tooltipSpanHack\n tooltipPlacement='top'\n />\n )}\n <p className='text-truncate mb-0 overflow-visible'>\n {user.email ?\n user.email :\n (\n <span className='fst-italic'>\n <Text namespace={namespace} phrase='noEmail' />\n </span>\n )\n }\n </p>\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { UserRole } from 'libs/shared/enums/UserRole';\nimport { User } from 'libs/shared/interfaces';\n\nconst namespace = 'userManager.userList';\n\ninterface RoleOrYearGroupProps {\n userType: UserGroup;\n user?: Partial<User>;\n countryCode?: string;\n badgeText?: string;\n}\n\nfunction getBadgeText(props: RoleOrYearGroupProps): string {\n if (props.userType === UserGroup.Learner) {\n if (props.user?.masterYearGroup?.name)\n return props.user?.masterYearGroup.name;\n\n if (props.user?.yearGroups?.data?.length)\n return ArrayHelper.first(props.user?.yearGroups.data).name;\n\n return null;\n }\n\n if (props.userType === UserGroup.Staff) {\n if (props.user?.userProfile?.role === UserRole.Admin)\n return LanguageService.getPhrase(namespace, 'admin');\n \n if (props.user?.userProfile?.role === UserRole.SuperAdmin)\n return LanguageService.getPhrase(namespace, props.countryCode === 'US' ? 'superAdminUs' : 'superAdmin');\n\n return null;\n }\n}\n\nexport function RoleOrYearGroup(props: RoleOrYearGroupProps): JSX.Element {\n const badgeText = props.badgeText || getBadgeText(props);\n\n if (!badgeText)\n return <></>;\n\n return (\n <div className='rounded-pill border border-dark bg-white px-2 me-3 d-inline-block flex-shrink-0'>\n {badgeText}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Avatar } from 'libs/shared/components/avatar/Avatar';\nimport { User } from 'libs/shared/interfaces';\nimport { UserHelper } from 'libs/shared/utils/UserHelper';\n\nimport styles from './user-item-components.module.scss';\n\ninterface UserItemAvatarProps {\n user: Partial<User>;\n imageCdnUrl: string;\n}\n\nexport function UserItemAvatar(props: UserItemAvatarProps): JSX.Element {\n return (\n <div className={`${styles.avatarContainer} mx-2`}>\n <Avatar\n imageUrl={props.user.avatar?.url}\n imageCdnUrl={props.imageCdnUrl}\n initials={UserHelper.getInitials(props.user.name, props.user.surname)}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { BaseUserItemProps } from 'libs/shared/apps/user-manager/components/user-list/UserList';\nimport { BasicUserDetails } from 'libs/shared/apps/user-manager/components/user-list-items/components/BasicUserDetails';\nimport { RoleOrYearGroup } from 'libs/shared/apps/user-manager/components/user-list-items/components/RoleOrYearGroup';\nimport { UserItemAvatar } from 'libs/shared/apps/user-manager/components/user-list-items/components/UserItemAvatar';\nimport { CurrentUser } from 'libs/shared/interfaces';\n\ninterface BulkUserActionsErroredUserItemProps extends BaseUserItemProps {\n imageCdnUrl: string;\n errorMessage: string;\n currentUser?: CurrentUser;\n}\n\nexport function BulkUserActionsErroredUserItem(props: BulkUserActionsErroredUserItemProps): JSX.Element {\n return (\n <li className='d-flex align-items-center p-2'>\n <UserItemAvatar user={props.user} imageCdnUrl={props.imageCdnUrl} />\n\n <BasicUserDetails user={props.user} currentUser={props.currentUser} />\n\n <RoleOrYearGroup userType={props.userType} user={props.user} />\n\n <p className='mb-0 mx-2 text-danger'>\n {props.errorMessage}\n </p>\n </li>\n );\n}\n","export enum UserManagerClient {\n Online = 'online',\n Primary = 'primary',\n Curator = 'curator'\n}\n","import React from 'react';\n\ntype WizardContext = {\n disableNext?: boolean,\n setDisableNext?: (val: boolean) => void,\n\n onClickConfirm?: () => void,\n setOnClickConfirm?: (cb: () => void) => void,\n\n showButtons?: boolean,\n setShowButtons?: (val: boolean) => void,\n\n showSpinner?: boolean,\n setShowSpinner?: (val: boolean) => void\n};\n\nexport const WizardLayoutContext = React.createContext<WizardContext>({});\n\nexport const WizardLayoutContextProvider = (props: React.PropsWithChildren<any>) => {\n const [ disableNext, setDisableNext ] = React.useState(false);\n const [ onClickConfirm, setOnClickConfirm ] = React.useState(null);\n const [ showButtons, setShowButtons ] = React.useState(true);\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n\n return (\n <WizardLayoutContext.Provider value={{\n disableNext,\n setDisableNext,\n onClickConfirm,\n setOnClickConfirm,\n showButtons,\n setShowButtons,\n showSpinner,\n setShowSpinner\n }}>\n {props.children}\n </WizardLayoutContext.Provider>\n );\n};\n","export enum BatchDataType {\n Unknown = 0,\n Staff = 1,\n Learner = 2,\n MasterVideo = 3,\n Rostering = 8,\n MarketingProfile = 16\n}\n","export enum BatchJobName {\n YearGroupRollover = 'year-group-rollover',\n ChangeYearGroup = 'change-year-group',\n DeleteUser = 'delete-user',\n RemoveUser = 'remove-user',\n DeactivateUser = 'deactivate-user',\n ActivateUser = 'activate-user',\n AddToClassroom = 'add-to-classroom',\n ResetPassword = 'reset-password',\n SendResetPasswordEmail = 'send-reset-password-email',\n SendAccountActivationEmail = 'send-account-activation-email',\n CreateUser = 'create-user',\n\n AddToAudience = 'add-to-audience',\n AddToBackboneClassification = 'add-to-backbone-classification',\n AddToBackboneAudience = 'add-to-backbone-audience',\n AddToClassification = 'add-to-classification',\n AddToSeries = 'add-to-series',\n AddToDirector = 'add-to-director',\n AddToDistributor = 'add-to-distributor',\n AddToProductionCompany = 'add-to-production-company',\n AddToProducer = 'add-to-producer',\n SetProductionYear = 'set-production-year',\n AddToLibrary = 'add-to-library',\n AddToCurationTag = 'add-to-curation-tag',\n AddToSkillTag = 'add-to-skill-tag',\n AddToPedagogyTag = 'add-to-pedagogy-tag',\n AddToNormalTag = 'add-to-normal-tag',\n AddToHiddenTag = 'add-to-hidden-tag',\n AddResourceAndLink = 'add-resource-and-link',\n\n Rostering = 'rostering',\n MarketingProfile = 'marketing-profile',\n UpdateProspectDomains = 'update-prospect-domains',\n AddAliases = 'add-aliases',\n AddPartnerProfiles = 'add-partner-profiles'\n}\n","export enum BatchJobResultErrorCode {\n NoAction = 1,\n // eslint-disable-next-line @typescript-eslint/no-duplicate-enum-values\n Succeed = 1,\n Unknown = 10,\n\n CustomerNotFound = 100,\n UserNotFound = 101,\n\n EmailNotVerified = 131,\n UserDisabled = 133,\n\n InvalidYearGroup = 200,\n MissingYearGroup = 201,\n NewYearGroupNotSet = 202,\n\n ObjectNotFoundInBackboneClassification = 300,\n ObjectNotFoundInBackboneAudience = 301\n}\n","export enum BatchJobType {\n RolloverYearGroup = 1,\n DeactivateUser = 2,\n ChangeYearGroup = 3,\n DeleteUser = 4,\n CreateUser = 5,\n ResetPassword = 6,\n AddUsersClassroom = 7,\n SendAccountReminderEmail = 8,\n ActivateUser = 9,\n AddToBackboneClassification = 10,\n AddToClassification = 11,\n AddToBackboneAudience = 12,\n AddToAudience = 13,\n AddVideosSeries = 14,\n AddVideosDistributor = 15,\n AddVideosProductionCompany = 16,\n AddVideosProducer = 17,\n AddVideosDirector = 18,\n AddVideosLibrary = 19,\n AddVideosResourceAndLinks = 21,\n AddVideosTag = 22,\n SendAccountActivationEmail = 23,\n RemoveUser = 24,\n Rostering = 25,\n MarketingProfile = 26,\n SetProductionYear = 28,\n UpdateProspectDomains = 29,\n AddAliases = 30,\n AddPartnerProfiles = 31\n}\n","import React from 'react';\n\nexport function KeySvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M12.335 4C14.7258 4.00011 16.6631 5.90392 16.6631 8.26074C16.6629 9.95954 15.6586 11.3904 13.877 12.2334L15.2314 13.5742C15.4776 13.8297 15.4899 14.2192 15.2373 14.4619L13.7734 15.8994L14.7773 16.8828C15.0235 17.1318 15.0366 17.5149 14.7842 17.7705L12.7822 19.7441C12.523 19.9933 12.153 19.9618 11.8809 19.7383L10.8252 18.8252C10.6373 18.6591 10.5723 18.4158 10.5723 18.2051V12.1758C8.99791 11.4924 8.00018 9.97233 8 8.26074C8 5.89108 9.9246 4 12.335 4ZM12.335 5.02832C10.5078 5.02832 9.03711 6.47232 9.03711 8.26074C9.03732 9.79975 10.0929 11.096 11.6152 11.4346V18.0264L12.335 18.7285L13.7471 17.3174L12.8271 16.4229V15.3633L14.2012 14.0283L12.9307 12.7695V11.4795C14.5568 11.0963 15.6199 9.78709 15.6201 8.26074C15.6201 6.47238 14.1556 5.02843 12.335 5.02832ZM12.3496 5.875C13.125 5.875 13.7559 6.50584 13.7559 7.28125C13.7559 8.05666 13.125 8.6875 12.3496 8.6875C11.5744 8.68728 10.9434 8.05652 10.9434 7.28125C10.9434 6.50598 11.5744 5.87522 12.3496 5.875ZM12.3496 6.8125C12.0913 6.81272 11.8809 7.02291 11.8809 7.28125C11.8809 7.53959 12.0913 7.74978 12.3496 7.75C12.6081 7.75 12.8184 7.53972 12.8184 7.28125C12.8184 7.02278 12.6081 6.8125 12.3496 6.8125Z'\n />\n </svg>\n );\n}\n","import React from 'react';\n\nimport { DevError } from 'libs/common/backbone/errors/DevError';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { FilterOption } from 'libs/shared/apps/search/interfaces';\nimport { BulkUserActionOptions, BulkUserActionStepId, BulkUserSubAction } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/layout/BulkUserActionsWizardLayout';\nimport { BulkUserActivationActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/activation-action-info/BulkUserActivationActionInfo';\nimport { BulkUserActivationEmailActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/activation-email-info/BulkUserActivationEmailActionInfo';\nimport { BulkAddToClassroomActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/add-to-classroom-action-info/BulkAddToClassroomActionInfo';\nimport { BulkChangeYearGroupActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/change-year-group-action-info/ChangeYearGroupActionInfo';\nimport { BulkUserDeleteActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/delete-action-info/BulkUserDeleteActionInfo';\nimport { BulkUserRemoveActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/remove-action-info/BulkUserRemoveActionInfo';\nimport { BulkUserResetEmailActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/reset-email-info/BulkUserResetEmailActionInfo';\nimport { BulkResetPasswordActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/reset-password-action-info/BulkResetPasswordActionInfo';\nimport { BulkUserYearGroupRolloverActionInfo } from 'libs/shared/apps/user-manager/components/bulk-actions-wizard/select-action/year-group-rollover-action-info/BulkUserYearGroupRolloverActionInfo';\nimport { BulkUserActionsErroredUserItem } from 'libs/shared/apps/user-manager/components/user-list-items/bulk-user-actions-errored-user-item/BulkUserActionsErroredUserItem';\nimport { UserManagerClient } from 'libs/shared/apps/user-manager/enums/UserManagerClient';\nimport { AllowYearGroupRollover } from 'libs/shared/apps/user-manager/hooks/useAllowAnnualYearGroupRollover';\nimport { UserManagerAppLinks } from 'libs/shared/apps/user-manager/interfaces';\nimport { UserManagerQueryParams } from 'libs/shared/apps/user-manager/interfaces/query-params/UserManagerQueryParams';\nimport { BulkUserActionsAddToClassroomViewModel, BulkUserActionsResetPasswordViewModel, BulkUserActionsViewModel, BulkUserActionsYearGroupRolloverViewModel } from 'libs/shared/apps/user-manager/interfaces/viewmodels/BulkUserActionsViewModel';\nimport { WizardOptionHash } from 'libs/shared/components/wizard/options/WizardOptions';\nimport { ObjectWithErrorCode } from 'libs/shared/components/wizard/status/statuses/completed-with-error/WizardCompletedWithError';\nimport { WizardStep } from 'libs/shared/components/wizard/step-list/WizardStepList';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { WizardLayoutContext } from 'libs/shared/context/WizardLayoutContext';\nimport { BatchDataType } from 'libs/shared/enums/BatchDataType';\nimport { BatchJobName } from 'libs/shared/enums/BatchJobName';\nimport { BatchJobResultErrorCode } from 'libs/shared/enums/BatchJobResultErrorCode';\nimport { BatchJobType } from 'libs/shared/enums/BatchJobType';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { DeleteSvg } from 'libs/shared/images/svg/actions/DeleteSvg';\nimport { ClassroomsSvg } from 'libs/shared/images/svg/objects/ClassroomsSvg';\nimport { EmailSvg } from 'libs/shared/images/svg/objects/EmailSvg';\nimport { FolderSvg } from 'libs/shared/images/svg/objects/FolderSvg';\nimport { GraduationCapSvg } from 'libs/shared/images/svg/objects/GraduationCapSvg';\nimport { GroupSvg } from 'libs/shared/images/svg/objects/GroupSvg';\nimport { KeySvg } from 'libs/shared/images/svg/objects/KeySvg';\nimport { AddToClassroomJobMetadata, BaseBatchJobMetadata, BatchJobMetadata, ChangeYearGroupJobMetadata, CreateBatchJobRequest, CurrentUser, ResetPasswordJobMetadata, User, WizardActionVerb, YearGroup, YearGroupRolloverJobMetadata } from 'libs/shared/interfaces';\nimport { CountsByStatus } from 'libs/shared/interfaces/models/SearchAggregation';\n\nconst getPhrase = LanguageService.encloseNamespace('userManager.utils');\n\nexport const SUPPORTED_BATCH_JOB_TYPES = [\n BatchJobType.ActivateUser,\n BatchJobType.AddUsersClassroom,\n BatchJobType.ChangeYearGroup,\n BatchJobType.DeactivateUser,\n BatchJobType.DeleteUser,\n BatchJobType.ResetPassword,\n BatchJobType.RolloverYearGroup,\n BatchJobType.SendAccountReminderEmail,\n BatchJobType.CreateUser,\n BatchJobType.SendAccountActivationEmail,\n BatchJobType.RemoveUser\n];\n\nexport const BulkUserActionsHelper = {\n getSteps(\n userType: UserGroup,\n userCount: number,\n appLinks?: UserManagerAppLinks,\n action?: BulkUserActionOptions\n ): WizardStep<BulkUserActionStepId>[] {\n const actions: WizardStep<BulkUserActionStepId>[] = [\n {\n id: 'select-action',\n text: getPhrase('choose'),\n appLink: appLinks?.bulkActionsSelectAction\n },\n {\n id: 'action-details',\n text: getPhrase('details'),\n appLink: appLinks?.bulkActionsActionDetails?.[action],\n disabled: !appLinks?.bulkActionsActionDetails?.[action]\n },\n {\n id: 'confirmation',\n text: getPhrase('confirmation')\n },\n {\n id: 'status',\n text: getPhrase('status')\n }\n ];\n\n const reviewAccountsAction: WizardStep<BulkUserActionStepId> = {\n id: 'review-accounts',\n text: getPhrase(userType === UserGroup.Learner ? 'reviewStudents' : 'reviewStaff'),\n subText: getPhrase(userType === UserGroup.Learner ? 'reviewSubTextStudents' : 'reviewSubTextStaff', { smartCount: userCount }),\n appLink: appLinks?.bulkActionsReviewAccounts\n };\n\n if (typeof (userCount) !== 'number')\n delete reviewAccountsAction.subText;\n\n actions.unshift(reviewAccountsAction);\n\n return actions;\n },\n\n getActionOptions({\n userType,\n allowYearGroupRollover,\n countsByStatus,\n client,\n products,\n yearGroups,\n hasClassroomsFeature\n }: {\n userType: UserGroup,\n allowYearGroupRollover: AllowYearGroupRollover,\n countsByStatus: CountsByStatus,\n client: UserManagerClient,\n products?: ProductId[],\n yearGroups?: YearGroup[],\n hasClassroomsFeature: boolean\n }): WizardOptionHash<BulkUserActionOptions>[] {\n const actions: WizardOptionHash<BulkUserActionOptions>[] = [];\n\n actions.push({\n order: 40,\n id: 'activation',\n icon: FolderSvg,\n name: getPhrase('deactivateReactivate'),\n infoComponent: () => <BulkUserActivationActionInfo userType={userType} />\n });\n\n const disableDeleteAction = !countsByStatus?.Disabled && !countsByStatus?.Inactive;\n\n const showDelete = client !== UserManagerClient.Primary || products?.includes(ProductId.Online);\n if (showDelete) {\n actions.push({\n order: 50,\n id: 'delete',\n icon: DeleteSvg,\n name: getPhrase('delete'),\n infoComponent: () => <BulkUserDeleteActionInfo userType={userType} />,\n disabled: disableDeleteAction,\n tooltip: disableDeleteAction ? getPhrase('deleteDisabledTooltip') : ''\n });\n }\n const showRemove = client !== UserManagerClient.Online && !products?.includes(ProductId.Online);\n\n if (showRemove) {\n actions.push({\n order: 50,\n id: 'removeFromSchool',\n icon: DeleteSvg,\n name: getPhrase('removeFromSchool'),\n infoComponent: () => <BulkUserRemoveActionInfo userType={userType} />,\n disabled: disableDeleteAction,\n tooltip: disableDeleteAction ? getPhrase('removeFromSchoolDisabledTooltip') : ''\n });\n }\n\n if (userType === UserGroup.Learner) {\n if (yearGroups?.length > 1) {\n actions.push({\n order: 20,\n id: 'changeYearGroup',\n icon: GroupSvg,\n name: getPhrase('changeYearGroup'),\n infoComponent: () => <BulkChangeYearGroupActionInfo />\n });\n }\n \n actions.push({\n order: 30,\n id: 'resetPassword',\n icon: KeySvg,\n name: getPhrase('resetPassword'),\n // TODO: Replace all of these info components with a shared component that accepts a heading and message prop\n infoComponent: () => <BulkResetPasswordActionInfo />\n });\n\n actions.push({\n order: 35,\n id: 'activationEmail',\n icon: EmailSvg,\n name: getPhrase('activationEmail'),\n infoComponent: () => <BulkUserActivationEmailActionInfo />\n });\n\n if (hasClassroomsFeature) {\n actions.push({\n order: 60,\n id: 'addToClassroom',\n icon: ClassroomsSvg,\n name: getPhrase('addToClassroom'),\n infoComponent: () => <BulkAddToClassroomActionInfo />\n });\n }\n \n if (yearGroups?.length > 1) {\n actions.push({\n order: 70,\n id: 'yearGroupRollover',\n icon: GraduationCapSvg,\n name: getPhrase('yearGroupRollover'),\n infoComponent: () => <BulkUserYearGroupRolloverActionInfo />,\n disabled: !allowYearGroupRollover?.canRollover,\n tooltip: getYearGroupRolloverDisabledTooltip(allowYearGroupRollover)\n });\n }\n }\n\n if (userType === UserGroup.Staff) {\n actions.push({\n order: 60,\n id: 'resetEmail',\n icon: EmailSvg,\n name: getPhrase('resetEmail'),\n infoComponent: () => <BulkUserResetEmailActionInfo />\n });\n }\n\n return actions.sort((a, b) => a.order - b.order);\n },\n\n mapSubActionToDisplayName(subAction: BulkUserSubAction): string {\n switch (subAction) {\n case 'yearGroupRollover':\n return getPhrase('yearGroupRolloverDisplayName');\n case 'changeYearGroup':\n return getPhrase('changeYearGroupDisplayName');\n case 'deactivate':\n return getPhrase('deactivateDisplayName');\n case 'reactivate':\n return getPhrase('reactivateDisplayName');\n case 'delete':\n return getPhrase('deleteDisplayName');\n case 'addToClassroom':\n return getPhrase('addToClassroomDisplayName');\n case 'resetPassword':\n return getPhrase('resetPasswordDisplayName');\n case 'resetEmail':\n return getPhrase('resetEmailDisplayName');\n case 'activationEmail':\n return getPhrase('activationEmailDisplayName');\n case 'removeFromSchool':\n return getPhrase('removeFromSchoolDisplayName');\n default:\n return '';\n }\n },\n\n getWizardAppLinks(appLinks: UserManagerAppLinks): Core.AppLink[] {\n const actionDetailsActions = Object.keys(appLinks.bulkActionsActionDetails)\n .map((key: keyof typeof appLinks.bulkActionsActionDetails) => {\n return appLinks.bulkActionsActionDetails[key];\n });\n\n const confirmationAppLinks = Object.keys(appLinks.bulkActionsConfirmation)\n .map((key: keyof typeof appLinks.bulkActionsConfirmation) => {\n return appLinks.bulkActionsConfirmation[key];\n });\n\n const statusAppLinks = Object.keys(appLinks.bulkActionsStatus)\n .map((key: keyof typeof appLinks.bulkActionsStatus) => {\n return appLinks.bulkActionsStatus[key];\n });\n\n return [\n appLinks.bulkActionsReviewAccounts,\n appLinks.bulkActionsSelectAction,\n ...actionDetailsActions,\n ...confirmationAppLinks,\n ...statusAppLinks\n ];\n },\n\n getErrorListItem(\n object: ObjectWithErrorCode<User>,\n imageCdnUrl: string,\n currentUser?: CurrentUser\n ): JSX.Element {\n const errorMessage = this.getUserErrorMessage(object.errorCode);\n return (\n <BulkUserActionsErroredUserItem\n user={object}\n userType={object.userType}\n imageCdnUrl={imageCdnUrl}\n errorMessage={errorMessage}\n currentUser={currentUser}\n />\n );\n },\n\n getUserErrorMessage(errorCode: BatchJobResultErrorCode): string {\n switch (errorCode) {\n case BatchJobResultErrorCode.NoAction:\n case BatchJobResultErrorCode.Succeed:\n return '';\n\n case BatchJobResultErrorCode.InvalidYearGroup:\n return getPhrase('invalidYearGroupError');\n case BatchJobResultErrorCode.MissingYearGroup:\n return getPhrase('missingYearGroupError');\n case BatchJobResultErrorCode.NewYearGroupNotSet:\n return getPhrase('yearGroupUpdateError');\n\n case BatchJobResultErrorCode.EmailNotVerified:\n return getPhrase('emailNotVerifiedError');\n\n case BatchJobResultErrorCode.UserDisabled:\n return getPhrase('userDeactivatedError');\n\n /**\n * I feel like by the this point, none of these errors should be getting thrown.\n * If they do get thrown, we use a generic error message and append the error code\n * in case it does happen and a screenshot is sent to support (hoping this helps).\n */\n case BatchJobResultErrorCode.Unknown:\n case BatchJobResultErrorCode.CustomerNotFound:\n case BatchJobResultErrorCode.UserNotFound:\n default:\n return getPhrase('genericUnexpectedError', { errorCode });\n }\n },\n\n getCreateJobRequestData(\n viewModel: BulkUserActionsViewModel,\n customerId: string,\n userType: UserGroup,\n currentUser?: CurrentUser\n ): CreateBatchJobRequest {\n switch (viewModel.subAction) {\n case 'yearGroupRollover': {\n return {\n name: BatchJobName.YearGroupRollover,\n type: BatchJobType.RolloverYearGroup,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getYearGroupRolloverJobMetadata(\n viewModel as BulkUserActionsYearGroupRolloverViewModel,\n customerId\n )\n };\n }\n\n case 'changeYearGroup': {\n return {\n name: BatchJobName.ChangeYearGroup,\n type: BatchJobType.ChangeYearGroup,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getChangeYearGroupJobMetadata(\n viewModel as BulkUserActionsYearGroupRolloverViewModel\n )\n };\n }\n\n case 'delete': {\n return {\n name: BatchJobName.DeleteUser,\n type: BatchJobType.DeleteUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'removeFromSchool': {\n return {\n name: BatchJobName.RemoveUser,\n type: BatchJobType.RemoveUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'deactivate': {\n return {\n name: BatchJobName.DeactivateUser,\n type: BatchJobType.DeactivateUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getDeactivateUsersJobMetadata(viewModel, currentUser)\n };\n }\n\n case 'reactivate': {\n return {\n name: BatchJobName.ActivateUser,\n type: BatchJobType.ActivateUser,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'addToClassroom': {\n return {\n name: BatchJobName.AddToClassroom,\n type: BatchJobType.AddUsersClassroom,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getAddToClassroomJobMetadata(\n viewModel as BulkUserActionsAddToClassroomViewModel\n )\n };\n }\n\n case 'resetPassword': {\n return {\n name: BatchJobName.ResetPassword,\n type: BatchJobType.ResetPassword,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: getResetPasswordJobMetadata(viewModel as BulkUserActionsResetPasswordViewModel)\n };\n }\n\n case 'resetEmail': {\n return {\n name: BatchJobName.SendResetPasswordEmail,\n type: BatchJobType.SendAccountReminderEmail,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n case 'activationEmail': {\n return {\n name: BatchJobName.SendAccountActivationEmail,\n type: BatchJobType.SendAccountActivationEmail,\n dataType: BulkUserActionsHelper.mapUserTypeToDataType(userType),\n customerId,\n metadata: setupBaseJobMetadata(viewModel)\n };\n }\n\n default:\n Core.ErrorHelper.throw(\n new DevError(`No handler for type ${viewModel.subAction} in BulkUserActionsHelper.getCreateJobRequestData`)\n );\n }\n\n return null;\n },\n\n useSetWizardConfirmationCallback(onClickConfirm: () => void): void {\n const { setOnClickConfirm } = React.useContext(WizardLayoutContext);\n const [viewModel] = useViewModel<BulkUserActionsViewModel>(SharedViewModelKeys.BULK_USER_ACTIONS);\n\n React.useEffect(() => {\n setOnClickConfirm(() => onClickConfirm);\n }, [viewModel?.subAction]);\n },\n\n useCreateJobErrorAlert(): () => void {\n const alerts = useAlerts();\n return () => {\n alerts.error(getPhrase('failedToCreateJob'));\n };\n },\n\n mapDataTypeToUserType(dataType: BatchDataType): UserGroup {\n switch (dataType) {\n case BatchDataType.Staff:\n return UserGroup.Staff;\n case BatchDataType.Learner:\n return UserGroup.Learner;\n default:\n return UserGroup.Unknown;\n }\n },\n\n mapUserTypeToDataType(userType: UserGroup): BatchDataType {\n switch (userType) {\n case UserGroup.Learner:\n return BatchDataType.Learner;\n case UserGroup.Staff:\n return BatchDataType.Staff;\n case UserGroup.Unknown:\n return BatchDataType.Unknown;\n }\n },\n\n getActionTypeFilterOptions(): FilterOption<BatchJobType>[] {\n return [{\n id: BatchJobType.ActivateUser,\n name: getPhrase('activate')\n }, {\n id: BatchJobType.DeactivateUser,\n name: getPhrase('deactivate')\n }, {\n id: BatchJobType.DeleteUser,\n name: getPhrase('deleteUser')\n }, {\n id: BatchJobType.RolloverYearGroup,\n name: getPhrase('yearGroupRollover')\n }, {\n id: BatchJobType.ChangeYearGroup,\n name: getPhrase('changeYearGroup')\n }, {\n id: BatchJobType.CreateUser,\n name: getPhrase('createUser')\n }, {\n id: BatchJobType.ResetPassword,\n name: getPhrase('resetPassword')\n }, {\n id: BatchJobType.SendAccountReminderEmail,\n name: getPhrase('resetEmail')\n }, {\n id: BatchJobType.AddUsersClassroom,\n name: getPhrase('addToClassroom')\n }, {\n id: BatchJobType.SendAccountActivationEmail,\n name: getPhrase('activationEmail')\n }, {\n id: BatchJobType.RemoveUser,\n name: getPhrase('removeFromSchool')\n }];\n },\n\n getUserTypeFilterOptions(): FilterOption<UserGroup>[] {\n return [{\n id: UserGroup.Staff,\n name: getPhrase('staff')\n }, {\n id: UserGroup.Learner,\n name: getPhrase('students')\n }];\n },\n\n mapSubActionToVerb(subAction: BulkUserSubAction): WizardActionVerb {\n if (subAction === 'delete')\n return 'Delete';\n\n if (subAction === 'removeFromSchool')\n return 'Remove';\n\n if (subAction === 'resetEmail' || subAction === 'activationEmail')\n return 'Email';\n\n if (subAction === 'addToClassroom')\n return 'Add';\n\n return 'Update';\n },\n\n mapJobTypeToName(type: BatchJobType): string {\n switch (type) {\n case BatchJobType.ActivateUser:\n return getPhrase('activate');\n case BatchJobType.AddUsersClassroom:\n return getPhrase('addToClassroom');\n case BatchJobType.ChangeYearGroup:\n return getPhrase('changeYearGroup');\n case BatchJobType.DeactivateUser:\n return getPhrase('deactivate');\n case BatchJobType.DeleteUser:\n return getPhrase('delete');\n case BatchJobType.ResetPassword:\n return getPhrase('resetPassword');\n case BatchJobType.RolloverYearGroup:\n return getPhrase('yearGroupRollover');\n case BatchJobType.SendAccountReminderEmail:\n return getPhrase('sendAccountReminderEmail');\n case BatchJobType.CreateUser:\n return getPhrase('bulkUpload');\n case BatchJobType.SendAccountActivationEmail:\n return getPhrase('sendAccountActivationEmail');\n case BatchJobType.RemoveUser:\n return getPhrase('removeUser');\n default:\n return getPhrase('unknown');\n }\n },\n\n hasFilterOrQuery(params: UserManagerQueryParams): boolean {\n return !!(params.query ||\n params.isAdmin ||\n params.status ||\n params.yearGroup);\n }\n};\n\nfunction setupBaseJobMetadata(\n viewModel: BulkUserActionsViewModel\n): BatchJobMetadata {\n return {\n batchObjectIds: [...viewModel.userIdMap.keys()],\n fullBatchObjects: undefined\n };\n}\n\nfunction getYearGroupRolloverJobMetadata(\n viewModel: BulkUserActionsYearGroupRolloverViewModel,\n customerId: string\n): YearGroupRolloverJobMetadata {\n // Year level rollover can only ever be run with all students\n return {\n fullBatchObjects: {\n source: 'UserApi',\n ownerId: customerId,\n objectType: MasterType.User,\n query: `{userType:${UserGroup.Learner}}`\n },\n finalYearGroupId: viewModel.yearGroup.id\n };\n}\n\nfunction getChangeYearGroupJobMetadata(\n viewModel: BulkUserActionsYearGroupRolloverViewModel\n): ChangeYearGroupJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as ChangeYearGroupJobMetadata;\n\n metadata.newYearGroupId = viewModel.yearGroup.id;\n\n return metadata;\n}\n\nfunction getResetPasswordJobMetadata(\n viewModel: BulkUserActionsResetPasswordViewModel\n): ResetPasswordJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as ResetPasswordJobMetadata;\n\n metadata.newPassword = viewModel.password;\n metadata.changeOnNextLogin = viewModel.changeOnNextLogin;\n\n return metadata;\n}\n\nfunction getYearGroupRolloverDisabledTooltip(status: AllowYearGroupRollover): string {\n if (status.canRollover)\n return '';\n\n switch (status.reason) {\n case 'select-all-students':\n return getPhrase('selectAllStudents');\n case 'cooldown':\n return getPhrase('rolloverCooldown', {\n date: DateHelper.format(status.lastRolloverDate, 'DD/MM/YYYY')\n });\n }\n}\n\nfunction getAddToClassroomJobMetadata(\n viewModel: BulkUserActionsAddToClassroomViewModel\n): AddToClassroomJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as AddToClassroomJobMetadata;\n\n metadata.classroomIds = [viewModel.classroom.id];\n\n return metadata;\n}\n\nfunction getDeactivateUsersJobMetadata(\n viewModel: BulkUserActionsViewModel,\n currentUser: CurrentUser\n): BatchJobMetadata {\n const metadata = setupBaseJobMetadata(viewModel) as BaseBatchJobMetadata;\n\n if (!currentUser?.id)\n return metadata;\n\n metadata.batchObjectIds = metadata.batchObjectIds?.filter(id => {\n return id.toString() !== currentUser.id.toString();\n }) ?? [];\n\n return metadata;\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { DurationFilterOptions, FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nconst namespace = 'search.durationFilter';\n\nfunction mapOptionToDurationRange(option: FilterOption<DurationFilterOptions>): string {\n let phraseKey = '';\n\n switch (option.id) {\n case 'bite-sized':\n phraseKey = 'rangeBiteSized';\n break;\n\n case 'short':\n phraseKey = 'rangeShort';\n break;\n \n case 'medium':\n phraseKey = 'rangeMedium';\n break;\n\n case 'long':\n phraseKey = 'rangeLong';\n break;\n }\n \n return LanguageService.getPhrase(namespace, phraseKey);\n}\n\ninterface DurationOptionProps {\n onClick: (option: FilterOption<DurationFilterOptions>) => void;\n option: FilterOption<DurationFilterOptions>;\n active: boolean;\n disabled?: boolean;\n}\n\nfunction DurationOption(props: DurationOptionProps): JSX.Element {\n return (\n <li className='d-flex flex-fill flex-column align-items-center mb-2 mb-md-0 mx-1'>\n <button\n onClick={() => props.onClick(props.option)}\n className={`btn w-100 text-center btn-${props.active ? 'dark' : 'outline-dark'} mb-1`}\n disabled={props.disabled}\n >\n {props.option.name}\n </button>\n\n <span>{mapOptionToDurationRange(props.option)}</span>\n </li>\n );\n}\n\nexport function DurationFilter(props: FilterProps): JSX.Element {\n const currentSelection = ArrayHelper.first(props.draftState.selection);\n\n function onClickDuration(duration: FilterOption<DurationFilterOptions>): void {\n // If the clicked option is already selected, deselect it\n if (currentSelection?.id === duration.id) {\n props.setDraftState({\n active: false,\n selection: []\n });\n \n return;\n }\n\n props.setDraftState({\n active: true,\n selection: [duration]\n });\n }\n\n return (\n <>\n <FilterDropdownTitle title={props.filter.name} />\n\n <ul className='d-flex list-unstyled flex-column flex-md-row mx-n1 mb-2'>\n {props.filter.options.map(option => (\n <DurationOption\n key={option.id}\n option={option as FilterOption<DurationFilterOptions>}\n onClick={onClickDuration}\n active={currentSelection?.id === option.id}\n disabled={props.filter.disabled || option.disabled}\n />\n ))}\n </ul>\n </>\n );\n}\n","export const XmasConstants = {\n IS_XMAS: false\n};\n",":local{\n .icon {\n width: 1.25rem;\n left: map-get($spacers, 2);\n }\n .activeIcon {\n width: 2.5rem;\n top: -#{map-get($spacers, 1)};\n left: 0.0625rem;\n transform: rotate(-16deg);\n }\n\n .text {\n margin-left: 1.625rem;\n }\n\n .floatingIcon {\n width: 1.875rem;\n transition: all 300ms;\n\n &.default {\n opacity: 0;\n top: -0.5rem;\n left: 1rem;\n }\n &.default.xmas {\n opacity: 0;\n top: 0.3rem;\n left: 0rem;\n }\n &.active {\n opacity: 1;\n top: -1.5rem;\n left: 2rem;\n }\n &.active.xmas {\n opacity: 1;\n scale: 0.8;\n top: -0.91857rem;\n left: 0rem;\n }\n }\n\n}","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterState } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { XmasConstants } from 'libs/shared/constants/XmasConstants';\n\nimport styles from './movies-and-tv-filter.module.scss';\n\nconst namespace = 'search.moviesAndTvFilter';\n\ninterface MoviesAndTvFilterProps {\n filter: SearchFilter;\n iconUrl: string;\n extraIconUrl: string;\n}\n\nexport function MoviesAndTvFilter(props: MoviesAndTvFilterProps): JSX.Element {\n const filter = props.filter;\n const { state } = React.useContext(FilterContext);\n\n const currentFilterState = state[filter.id];\n const isActive = currentFilterState?.active;\n\n // local state to correct attach & detach animation class\n const [ isFloating, setIsFloating ] = React.useState(false);\n const activeRef = React.useRef(isFloating);\n\n React.useEffect(() => {\n if (isActive !== activeRef.current) {\n activeRef.current = isActive;\n }\n if (isFloating !== activeRef.current)\n setIsFloating(activeRef.current);\n }, [isActive]);\n\n function applyFilter(newState: FilterState): void {\n FilterHelper.applyFilter(\n [filter],\n currentFilterState,\n { [props.filter.id]: newState },\n state.appLink\n );\n }\n \n return (\n <DivButton\n onClick={() => {\n setIsFloating(!isActive);\n applyFilter({ active: !isActive });\n }}\n className={classNames(\n 'mx-1 btn position-relative fw-semibold d-flex align-items-center flex-shrink-0',\n isActive ? 'btn-dark' : 'btn-outline-dark',\n props.filter.disabled && 'disabled'\n )}\n disabled={props.filter.disabled}\n >\n \n <img src={props.iconUrl} className={`${styles.icon} position-absolute ${isActive ? styles.activeIcon : ''}`}/>\n \n <div className={styles.text}>\n <Text namespace={namespace} phrase='title'/>\n </div>\n\n <img\n src={props.extraIconUrl}\n className={classNames(\n 'position-absolute',\n styles.floatingIcon,\n isFloating ? styles.active : styles.default,\n XmasConstants.IS_XMAS && styles.xmas\n )}\n />\n </DivButton>\n );\n}\n","import * as React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { FilterDropdownTitle } from 'libs/shared/apps/search/components/filter-dropdown-title/FilterDropdownTitle';\nimport { FilterOption, FilterProps } from 'libs/shared/apps/search/interfaces';\n\nimport { CheckboxFilterList } from '../checkbox-filter/CheckboxFilterList';\n\nexport function GroupedCheckboxFilter(props: FilterProps): JSX.Element {\n const optionGroups: Record<string, FilterOption[]> = {};\n\n for (const option of props.filter.options) {\n if (!option.group)\n continue;\n\n if (!optionGroups[option.group])\n optionGroups[option.group] = [];\n\n optionGroups[option.group].push(option);\n }\n\n return (\n <Form className='mb-3'>\n {Object.entries(optionGroups).map(([ groupName, options ]) => {\n return (\n <ul className='list-unstyled' key={groupName}>\n <FilterDropdownTitle title={groupName} />\n <CheckboxFilterList\n filter={props.filter}\n options={options}\n draftState={props.draftState}\n setDraftState={props.setDraftState}\n displayOptionsIn2Columns={false}\n />\n </ul>\n );\n })}\n </Form>\n );\n}\n","import { FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\n\nexport const ClassificationFilterHelper = {\n deriveInitialClassificationFilterStateFromQueryParams(filter: SearchFilter, selections: any): FilterOption[] {\n return filter?.options?.filter(option => {\n const areAllIdsInOptionFoundInSelections = option.id.split(':').every(id => {\n const isIdFoundInSelections = selections.find(\n (selectedId: number | string) => selectedId.toString() === id.toString()\n );\n\n return isIdFoundInSelections;\n });\n\n return areAllIdsInOptionFoundInSelections;\n }) ?? [];\n }\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { DurationFilterOptions, FilterOption } from 'libs/shared/apps/search/interfaces';\n\nconst namespace = 'sharedSearch.utils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport const DurationFilterHelper = {\n getOptions(): FilterOption<DurationFilterOptions>[] {\n return [\n {\n id: 'bite-sized',\n name: getPhrase('durationBiteSized')\n },\n {\n id: 'short',\n name: getPhrase('durationShort')\n },\n {\n id: 'medium',\n name: getPhrase('durationMedium')\n },\n {\n id: 'long',\n name: getPhrase('durationLong')\n }\n ];\n },\n\n getBackendParamValue(value: DurationFilterOptions): string {\n switch (value) {\n case 'bite-sized':\n return '...179999'; // 3 minutes in ms\n case 'short':\n return '180000...299999'; // 3 - 5 minutes in ms\n \n case 'medium':\n return '300000...899999'; // 5 - 15 minutes in ms\n \n case 'long':\n return '900000...'; // 15 minutes in ms\n }\n }\n};\n","import { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { FilterOption } from 'libs/shared/apps/search/interfaces';\n\nimport { getSelectedOptions } from './FilterHelper';\n\nexport const PresentationFilterHelper = {\n deriveInitialPresentationFilterStateFromQueryParams:\n (filterOptions: FilterOption[], selections: any, queryParams: HashObject): FilterOption[] => {\n return getSelectedOptions(filterOptions, selections)\n .map(option => {\n const audienceSelection = queryParams['audience'];\n\n if (!audienceSelection?.length)\n return option;\n\n const secondLayerSelection = getSelectedOptions(option.secondLayerOptions, audienceSelection);\n\n return { ...option, secondLayerSelection };\n }).filter(r => {\n return !!r.secondLayerSelection?.length;\n });\n }\n};\n","import { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { FilterOption, ProductionYearFilterOptions } from 'libs/shared/apps/search/interfaces';\n\nconst namespace = 'sharedSearch.utils';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport const ProductionYearFilterHelper = {\n getOptions(): FilterOption<ProductionYearFilterOptions>[] {\n return [\n {\n id: 'any-year',\n name: getPhrase('anyYear'),\n default: true\n },\n {\n id: 'this-year',\n name: getPhrase('thisYear')\n },\n {\n id: 'last-3-years',\n name: getPhrase('last3Years')\n },\n {\n id: 'last-5-years',\n name: getPhrase('last5Years')\n }\n ];\n },\n\n getBackendParamValue(value: ProductionYearFilterOptions): string {\n const currentYear = new Date().getFullYear();\n \n switch (value) {\n case 'any-year':\n return '';\n \n case 'this-year':\n return `${currentYear}...`;\n \n case 'last-3-years':\n return `${currentYear - 3}...`;\n \n case 'last-5-years':\n return `${currentYear - 5}...`;\n }\n }\n};\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { Rating, User, YearGroup } from 'libs/shared/interfaces';\n\nexport const RatingFilterHelper = {\n deriveInitialRatingFilterStateFromQueryParams(range: string | [], filter: SearchFilter): FilterOption[] {\n /**\n * When the rating filter is cleared, the app router temporarily sets the rating query param\n * value to an empty array instead of a string. In this case, we just return no selections\n */\n if (Array.isArray(range))\n return range;\n\n const ratingOptions = filter.options as Rating[];\n\n const ratingRange = getRatingsFromFrontendQuery(range, ratingOptions);\n\n if (!ratingRange.length)\n return [];\n\n const highestRating = ArrayHelper.last(ratingRange);\n\n return ratingOptions.filter(option => {\n return option.value > 0 && option.value <= highestRating.value;\n }) as FilterOption[];\n },\n\n getFrontendParamValue(selections: Rating[]): string {\n if (!selections?.length)\n return '';\n \n const first = ArrayHelper.first(selections);\n const last = ArrayHelper.last(selections);\n\n if (selections.length === 1)\n return first.code;\n \n return `${first.code}-to-${last.code}`;\n },\n \n getBackendParamValue(range: string, ratings: Rating[]): string {\n const selectedRatings = getRatingsFromFrontendQuery(range, ratings);\n \n if (!selectedRatings.length)\n return undefined;\n \n if (selectedRatings.length === 1) {\n const upperValue = ArrayHelper.first(selectedRatings);\n return `0...${upperValue.value}`;\n }\n \n const upperValue = ArrayHelper.last(selectedRatings);\n return `0...${upperValue.value}`;\n },\n\n getStudentMaxRating(yearGroups: YearGroup[], user: User): Rating {\n const studentYearGroup = ArrayHelper.findWhere(\n yearGroups,\n { value: user.masterYearGroup?.value }\n );\n\n return studentYearGroup?.rating;\n }\n};\n\nfunction getRatingsFromFrontendQuery(range: string, ratings: Rating[]): Rating[] {\n const codes = range.split('-to-');\n const foundRatings = codes.map(code => ratings.find(r => r.code === code));\n\n /**\n * If we can't map all our values, don't use any values.\n */\n if (!foundRatings.every(r => !!r))\n return [];\n\n return foundRatings;\n}\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, FilterDescriptor, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { CheckboxFilter, DropdownFilter, NestedCheckboxFilter, RadioFilter, SwitchFilter } from 'libs/shared/apps/search/components/filter-types';\nimport { RatingFilter } from 'libs/shared/apps/search/components/filter-types/rating-filter/RatingFilter';\nimport { FilterConstants } from 'libs/shared/apps/search/constants/FilterConstants';\nimport { AllSearchIndicesInSearch, AllSearchIndicesInUserManager, AllSearchIndicesVideoStyle, FilterIds, FilterOption, FilterProps, FilterType, FilterWhitelist, MoreFilters, SearchFilter, SearchIndices } from 'libs/shared/apps/search/interfaces';\nimport { AnalyticsFilterHash } from 'libs/shared/apps/search/interfaces/AnalyticsFilterHash';\nimport { DraftState, FilterPayloadType, FilterState, FilterStateHash } from 'libs/shared/apps/search/reducers';\nimport { SourceFilterHelper } from 'libs/shared/apps/search/utils/SourceFilterHelper';\nimport { TopicsConstants } from 'libs/shared/constants/TopicsConstants';\nimport { BatchJobType } from 'libs/shared/enums/BatchJobType';\nimport { CurationTag } from 'libs/shared/enums/CurationTag';\nimport { CustomerStatus, CustomerStatusString } from 'libs/shared/enums/CustomerStatus';\nimport { CustomerType, CustomerTypeString } from 'libs/shared/enums/CustomerType';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { BaseObject, Customer, Library, MasterNestedObject, PresentationWithAudiences, Rating, SpecialEventType, YearGroup } from 'libs/shared/interfaces';\n\nimport { SpecialEventTypeLabelMap } from '../../calendar/constants/SpecialEventTypeLabelMap';\nimport { BulkUserActionsHelper } from '../../user-manager/utils/BulkUserActionsHelper';\nimport { DurationFilter } from '../components/filter-types/custom/duration-filter/DurationFilter';\nimport { MoviesAndTvFilter } from '../components/filter-types/custom/movies-and-tv-filter/MoviesAndTvFilter';\nimport { GroupedCheckboxFilter } from '../components/filter-types/grouped-checkbox-filter/GroupedCheckboxFilter';\n\nimport { ClassificationFilterHelper } from './ClassificationFilterHelper';\nimport { DurationFilterHelper } from './DurationFilterHelper';\nimport { PresentationFilterHelper } from './PresentationFilterHelper';\nimport { ProductionYearFilterHelper } from './ProductionYearFilterHelper';\nimport { RatingFilterHelper } from './RatingFilterHelper';\nimport { SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM } from './SharedSearchHelper';\n\nconst getPhrase = LanguageService.encloseNamespace('sharedSearch.utils');\n\ntype MixinDisableFieldsFn = {\n mainFilters: SearchFilter[],\n moreFilters?: MoreFilters\n};\n\nconst TwoColumnFilters: Record<string, boolean> = {\n classification: true,\n categoryId: true,\n channel: true\n};\n\ninterface GetValidIndicesOptions {\n hasPartnerProfiles: boolean;\n}\n\nfunction getValidIndices(options: GetValidIndicesOptions): Record<string, boolean> {\n const allIndices: Record<string, boolean> = {\n series: true,\n video: true,\n playlist: true,\n classification: true,\n clip: true,\n interactive: true,\n company: true,\n category: true,\n partner_profile: false\n };\n\n if (options.hasPartnerProfiles) {\n allIndices.partner_profile = true;\n allIndices.company = false;\n }\n \n return allIndices;\n}\n\nexport const Filters: Filters = {\n SortBy: (options: FilterOption[], labelPrefix?: string) => ({\n id: 'sort',\n name: getPhrase('newest'),\n type: 'dropdown',\n options,\n compatibleIndices: [ ...AllSearchIndicesInSearch, ...AllSearchIndicesInUserManager ],\n labelPrefix\n }),\n Presentation: (options: PresentationWithAudiences[], _hasNewSearch: boolean) => ({\n id: 'presentation',\n secondaryId: 'audience',\n name: getPhrase('schoolLevels'),\n type: 'nested-checkbox',\n options: getMappedPresentationOptions(options),\n compatibleIndices: _hasNewSearch ?\n [ 'playlist', 'series', 'clip', 'interactive', 'video', 'company', 'category' ] :\n AllSearchIndicesInSearch\n }),\n Topics: (options: FilterOption[]) => ({\n compatibleIndices: [ 'playlist', 'series', 'clip', 'classification', 'interactive', 'video' ],\n options,\n type: 'checkbox',\n name: getPhrase('topicsFilter'),\n id: 'classification'\n }),\n Source: (options: FilterOption[]) => ({\n id: 'source',\n type: 'checkbox',\n name: getPhrase('sources'),\n options,\n compatibleIndices: [ 'video', 'clip', 'interactive', 'category' ]\n }),\n MoviesAndTv: (url: string, extraUrl: string) => ({\n id: 'moviesAndTv',\n name: getPhrase('moviesAndTv'),\n type: 'button',\n compatibleIndices: [ 'video', 'series', 'clip', 'interactive', 'classification', 'playlist', 'company' ],\n customComponent: props => (\n <MoviesAndTvFilter\n {...props}\n filter={props.filter as SearchFilter}\n iconUrl={url}\n extraIconUrl={extraUrl}\n />\n )\n }),\n YearGroup: (options: FilterOption[]) => ({\n id: 'yearGroup', // \"id\" should match the state keys in `FilterReducer`\n name: getPhrase('yearGroup'),\n type: 'checkbox',\n options,\n compatibleIndices: AllSearchIndicesInUserManager\n }),\n ObjectTypes: (inaccessibleIndices: SearchIndices[] = [], _hasNewSearch = false, _hasPartnerProfiles = false) => ({\n id: 'type',\n name: getPhrase('types'),\n type: _hasNewSearch ? 'grouped-checkbox' : 'checkbox',\n options: FilterHelper.getObjectTypeOptions(inaccessibleIndices, _hasNewSearch, _hasPartnerProfiles),\n disableOptions: FilterHelper.getIsObjectTypeOptionDisabled,\n compatibleIndices: AllSearchIndicesInSearch\n }),\n Rating: (options: FilterOption[], maxRating: Rating) => ({\n id: 'rating',\n name: getPhrase('rating'),\n description: getPhrase('ratingDescription'),\n type: 'rating',\n options: options && maxRating ? options.filter((rating: Rating) => rating.value <= maxRating.value) : options,\n compatibleIndices: [ 'video', 'series' ]\n }),\n Interactives: () => ({\n id: 'interactives',\n name: getPhrase('interactives'),\n type: 'switch',\n description: getPhrase('interactivesDescription'),\n compatibleIndices: [ 'video', 'clip' ]\n }),\n Clips: () => ({\n id: 'clips',\n name: getPhrase('clips'),\n type: 'switch',\n description: getPhrase('clipsDescription'),\n compatibleIndices: ['video']\n }),\n HasResources: () => ({\n id: 'hasResources',\n name: getPhrase('resources'),\n type: 'switch',\n description: getPhrase('resourcesDescription'),\n compatibleIndices: [ 'video', 'clip' ]\n }),\n HasSubtitles: () => ({\n id: 'hasSubtitles',\n name: getPhrase('subtitles'),\n type: 'switch',\n description: getPhrase('subtitlesDescription'),\n compatibleIndices: AllSearchIndicesVideoStyle\n }),\n ProductionYear: () => ({\n id: 'productionYear',\n name: getPhrase('productionYear'),\n type: 'radio',\n options: ProductionYearFilterHelper.getOptions(),\n compatibleIndices: [ ...AllSearchIndicesVideoStyle, 'series' ]\n }),\n IsHD: () => ({\n id: 'isHd',\n name: getPhrase('isHd'),\n type: 'switch',\n description: getPhrase('isHdDescription'),\n compatibleIndices: AllSearchIndicesVideoStyle\n }),\n IsClickViewContent: () => ({\n id: 'producedByClickView',\n name: getPhrase('producedByClickView'),\n type: 'switch',\n description: getPhrase('producedByClickViewDescription'),\n compatibleIndices: AllSearchIndicesInSearch\n }),\n Duration: () => ({\n id: 'duration',\n name: getPhrase('duration'),\n type: 'radio',\n customComponent: DurationFilter,\n options: DurationFilterHelper.getOptions(),\n compatibleIndices: AllSearchIndicesVideoStyle\n }),\n TagOrClassification: (options: string[]) => ({\n id: 'tagOrClassification',\n type: 'tag',\n options: options && options.map(option => ({\n id: option,\n name: option\n })),\n compatibleIndices: AllSearchIndicesInSearch\n }),\n Status: (options?: FilterOption[]) => ({\n id: 'status',\n name: getPhrase('status'),\n type: 'checkbox',\n compatibleIndices: [ ...AllSearchIndicesInUserManager, 'customer' ],\n options: options || FilterHelper.getStatusOptions()\n }),\n JobStatus: () => ({\n id: 'jobStatus',\n name: getPhrase('status'),\n type: 'checkbox',\n compatibleIndices: [],\n options: FilterHelper.getJobStatusOptions()\n }),\n IsAdmin: (customer: Customer, countryCode: string) => {\n const hasOrg = !!customer?.organisation;\n const isUs = countryCode === 'US';\n const description = !hasOrg ? getPhrase('isAdminDescription') :\n isUs ? getPhrase('isAdminDescriptionOrgUs') : getPhrase('isAdminDescriptionOrg');\n\n return {\n id: 'isAdmin',\n name: getPhrase('isAdmin'),\n type: 'switch',\n compatibleIndices: AllSearchIndicesInUserManager,\n description\n };\n },\n BulkActionType: () => ({\n id: 'bulkActionType',\n name: getPhrase('actionType'),\n type: 'checkbox',\n options: BulkUserActionsHelper.getActionTypeFilterOptions(),\n compatibleIndices: []\n }),\n UserType: () => ({\n id: 'userType',\n name: getPhrase('users'),\n type: 'checkbox',\n options: BulkUserActionsHelper.getUserTypeFilterOptions(),\n compatibleIndices: []\n }),\n TvFields: () => ({\n id: 'filter',\n name: getPhrase('tvFields'),\n type: 'radio',\n options: FilterHelper.getTvFieldsOptions(),\n compatibleIndices: []\n }),\n TvChannel: (channels: BaseObject[]) => ({\n id: 'channel',\n name: getPhrase('tvChannel'),\n type: 'checkbox',\n options: FilterHelper.getTvChannelOptions(channels),\n compatibleIndices: []\n }),\n TvDateBroadcast: () => ({\n id: 'dateBroadcast',\n name: getPhrase('tvDateBroadcast'),\n type: 'radio',\n options: FilterHelper.getTvDateBroadcastOptions(),\n compatibleIndices: []\n }),\n Categories: (categories: MasterNestedObject<Library>[]) => ({\n id: 'categoryId',\n name: getPhrase('categories'),\n type: 'checkbox',\n options: FilterHelper.getCategoriesOptions(categories),\n compatibleIndices: []\n }),\n CustomerStatus: () => ({\n id: 'customerStatus',\n name: getPhrase('customerStatus'),\n type: 'radio',\n options: FilterHelper.getCustomerStatusOptions(),\n compatibleIndices: []\n }),\n SpecialEventTypes: () => ({\n id: 'specialEventType',\n type: 'checkbox',\n name: 'Event Type',\n compatibleIndices: [],\n options: FilterHelper.getSpecialEventTypeOptions()\n }),\n CustomerType: () => ({\n id: 'customerType',\n name: getPhrase('customerType'),\n type: 'radio',\n options: FilterHelper.getCustomerTypeOptions(),\n compatibleIndices: []\n })\n};\n\ninterface Filters {\n SortBy: (options: FilterOption[], labelPrefix?: string) => SearchFilter;\n Presentation: (options: PresentationWithAudiences[], _hasNewSearch?: boolean) => SearchFilter;\n Topics: (options: FilterOption[]) => SearchFilter;\n YearGroup: (options: FilterOption[]) => SearchFilter;\n MoviesAndTv: (iconUrl: string, extraUrl: string) => SearchFilter;\n ObjectTypes: (\n inaccessibleIndices: SearchIndices[],\n _hasNewSearch?: boolean,\n _hasPartnerProfiles?: boolean\n ) => SearchFilter;\n Rating: (options: FilterOption[], maxRating: Rating) => SearchFilter;\n Interactives: () => SearchFilter;\n Clips: () => SearchFilter;\n HasResources: () => SearchFilter;\n HasSubtitles: () => SearchFilter;\n ProductionYear: () => SearchFilter;\n IsHD: () => SearchFilter;\n IsClickViewContent: () => SearchFilter;\n Duration: () => SearchFilter;\n TagOrClassification: (options: string[]) => SearchFilter;\n Status: (options?: FilterOption[]) => SearchFilter;\n JobStatus: () => SearchFilter;\n IsAdmin: (customer?: Customer, countryCode?: string) => SearchFilter;\n BulkActionType: () => SearchFilter<BatchJobType>;\n UserType: () => SearchFilter<UserGroup>;\n TvFields: () => SearchFilter;\n TvChannel: (channels: BaseObject[]) => SearchFilter;\n TvDateBroadcast: () => SearchFilter;\n Categories: (categories: MasterNestedObject<Library>[]) => SearchFilter;\n Source: (options: FilterOption[]) => SearchFilter;\n CustomerStatus: () => SearchFilter;\n SpecialEventTypes: () => SearchFilter;\n CustomerType: () => SearchFilter;\n}\n\nfunction getMappedPresentationOptions(options: PresentationWithAudiences[]): FilterOption[] {\n if (!options)\n return [];\n\n return options.map(opt => ({\n ...opt,\n id: opt.id.toString(),\n secondLayerOptions: opt.audiences.map(a => ({ ...a, id: a.id.toString() }))\n }));\n}\n\nexport const FilterHelper = {\n displayTwoLayers(filter: SearchFilter): boolean {\n if (filter.type !== 'nested-checkbox')\n return false;\n\n // With one presso we only show second layer options\n if (!this.hasManyFilterOptions(filter.options))\n return false;\n\n // Show first layer only\n if (filter.options.every(o => !this.hasManyFilterOptions(o?.secondLayerOptions)))\n return false;\n\n return true;\n },\n\n hasManyFilterOptions(options: FilterOption[]) {\n return options.length >= TopicsConstants.MULTI_PRESENTATION_THRESHOLD;\n },\n\n displayTwoColumns(filter: SearchFilter | MoreFilters): boolean {\n return (\n (TwoColumnFilters[filter.id]) &&\n filter.options?.length >= FilterConstants.MAX_CHECKBOXES_PER_COLUMN\n );\n },\n\n showPresentationFilter(presentationFilter: SearchFilter): boolean {\n // If the school's topic presentation has no audiences, don't show\n if (!presentationFilter.options?.length)\n return false;\n\n // If the school has more than 1 topic presentation, always show\n if (presentationFilter.options.length > 1)\n return true;\n \n // If the school has only 1 topic presentation but it has >1 audience, always show\n if (ArrayHelper.first(presentationFilter.options).secondLayerOptions?.length > 1)\n return true;\n\n return false;\n },\n\n getMoreFilters(filters: SearchFilter[]): MoreFilters {\n return {\n id: 'moreFilters',\n name: getPhrase('moreFilters'),\n type: 'more-filters',\n filters\n };\n },\n\n mapTypeToComponent(type: FilterType): (props: FilterProps) => JSX.Element {\n switch (type) {\n case 'switch':\n return (props: any) => <SwitchFilter key={props.id} {...props} />;\n case 'checkbox':\n return (props: any) => <CheckboxFilter key={props.id} {...props} />;\n case 'nested-checkbox':\n return (props: any) => <NestedCheckboxFilter key={props.id} {...props} />;\n case 'grouped-checkbox':\n return (props: any) => <GroupedCheckboxFilter key={props.id} {...props} />;\n case 'radio':\n return (props: any) => <RadioFilter key={props.id} {...props} />;\n case 'rating':\n return (props: any) => <RatingFilter key={props.id} {...props} />;\n case 'dropdown':\n return (props: any) => <DropdownFilter key={props.id} {...props} />;\n default:\n return () => <></>;\n }\n },\n\n deriveInitialStateFromQuery(\n queryParams: HashObject = {},\n mainFilters: SearchFilter[] = null,\n moreFilters: MoreFilters = null,\n appLink: Core.AppLink\n ): FilterStateHash {\n const initialStates: Omit<FilterStateHash, 'appLink' | 'moreFilters'> = {\n sort: {\n active: !!queryParams.sort,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'sort')\n },\n\n classification: {\n active: !!queryParams.classification,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'classification')\n },\n\n presentation: {\n active: !!queryParams.presentation,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'presentation')\n },\n\n type: {\n active: !!queryParams.type,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'type')\n },\n\n specialEventType: {\n active: !!queryParams.specialEventType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'specialEventType')\n },\n\n rating: {\n active: !!queryParams.rating,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'rating')\n },\n \n interactives: {\n active: queryParams.interactives?.toString() === 'true'\n },\n\n clips: {\n active: queryParams.clips?.toString() === 'true'\n },\n\n yearGroup: {\n active: !!queryParams.yearGroup,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'yearGroup')\n },\n\n moviesAndTv: {\n active: queryParams.moviesAndTv?.toString() === 'true'\n },\n\n classroom: {\n active: !!queryParams.classroom,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'classroom')\n },\n\n audience: {\n active: !!queryParams.audience,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'audience')\n },\n\n hasResources: {\n active: queryParams.hasResources?.toString() === 'true'\n },\n\n hasSubtitles: {\n active: queryParams.hasSubtitles?.toString() === 'true'\n },\n\n productionYear: {\n active: !!queryParams.productionYear,\n selection: getFilterSelectionsFromQueryParams(queryParams, moreFilters?.filters, 'productionYear')\n },\n\n isHd: {\n active: queryParams.isHd?.toString() === 'true'\n },\n\n producedByClickView: {\n active: queryParams.producedByClickView?.toString() === 'true'\n },\n\n duration: {\n active: queryParams.duration,\n selection: getFilterSelectionsFromQueryParams(queryParams, moreFilters?.filters, 'duration')\n },\n\n tagOrClassification: {\n active: !!queryParams.tagOrClassification,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'tagOrClassification')\n },\n\n status: {\n active: !!queryParams.status,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'status')\n },\n\n jobStatus: {\n active: !!queryParams.jobStatus,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'jobStatus')\n },\n isAdmin: {\n active: queryParams.isAdmin?.toString() === 'true'\n },\n\n bulkActionType: {\n active: !!queryParams.bulkActionType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'bulkActionType')\n },\n\n userType: {\n active: !!queryParams.userType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'userType')\n },\n\n filter: {\n active: !!queryParams.filter,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'filter')\n },\n\n channel: {\n active: !!queryParams.channel,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'channel')\n },\n\n dateBroadcast: {\n active: !!queryParams.dateBroadcast,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'dateBroadcast')\n },\n\n categoryId: {\n active: !!queryParams.categoryId,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'categoryId')\n },\n \n hasInteractives: {\n active: !!queryParams.hasInteractives,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'hasInteractives')\n },\n\n source: {\n active: !!queryParams.source,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'source')\n },\n\n customerStatus: {\n active: !!queryParams.customerStatus,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'customerStatus')\n },\n\n customerType: {\n active: !!queryParams.customerType,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'customerType')\n },\n\n seriesId: {\n active: !!queryParams.seriesId,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'seriesId')\n },\n\n scopeId: {\n active: !!queryParams.scopeId,\n selection: getFilterSelectionsFromQueryParams(queryParams, mainFilters, 'scopeId')\n }\n };\n\n const reduceFunc = (state: FilterStateHash, filter: SearchFilter<string>) => {\n const filterState = initialStates[filter.id];\n\n /**\n * If we had the query param value, but were not able to parse it into a valid selection.\n * We're actually not active.\n * \n * e.g. For `?rating=bleep-to-bloop` the value of !!queryParams.rating is true, but we are not able\n * to extract any meaningful values from it so the call to getFilterSelectionsFromQueryParams returns an empty array.\n * \n * - Sha\n */\n if (filterState.active && 'selection' in filterState && !filterState.selection?.length)\n filterState.active = false;\n\n state[filter.id] = initialStates[filter.id];\n return state;\n };\n\n const derivedState = mainFilters.reduce<FilterStateHash>(reduceFunc, {} as FilterStateHash);\n\n if (moreFilters?.filters) {\n derivedState.moreFilters = moreFilters.filters.reduce<FilterStateHash>(reduceFunc, {} as FilterStateHash);\n }\n\n derivedState.appLink = appLink;\n\n return derivedState;\n },\n\n hasActiveFilters(queryParams: HashObject): boolean {\n const paramKeys = Object.keys(queryParams);\n\n if (!paramKeys.length)\n return false;\n\n const activeFilters = paramKeys.filter(q => {\n // 'query', 'cursor', 'page', 'scopeId' and 'curriculumCode' don't count as filters\n if ([ 'query', 'cursor', 'page', SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM ].includes(q))\n return false;\n\n // Filters that can have multiple selections (e.g. checkbox types) do not count as active if they are empty\n if (Array.isArray(queryParams[q]) && !queryParams[q].length)\n return false;\n\n return true;\n });\n\n return !!activeFilters.length;\n },\n\n getLabel(filter: SearchFilter, filterState: FilterState): string {\n if (!filterState?.selection?.length)\n return filter.name;\n\n if (filter.type === 'dropdown')\n return ArrayHelper.first(filterState.selection).name;\n\n if (filter.type === 'radio') {\n const selection = ArrayHelper.first(filterState.selection);\n if (!selection || selection.default)\n return filter.name;\n\n return selection.name;\n }\n\n if (filter.type === 'nested-checkbox' || filter.type === 'checkbox' || filter.type === 'grouped-checkbox') {\n const isDefaultState = filter.options.find(opt => {\n return opt.default && filterState.selection.find(selection => selection.id === opt.id);\n });\n\n if (isDefaultState)\n return filter.name;\n\n if (filter.secondaryId) {\n const count = filterState.selection?.reduce((acc, firstLayerSelection) => {\n const availableOptions = filter.options;\n const index = availableOptions.findIndex(option => option.id === firstLayerSelection.id);\n if (availableOptions[index].secondLayerOptions?.length === 0) {\n return acc + 1;\n }\n\n return acc + (firstLayerSelection.secondLayerSelection?.length ?? 0);\n }, 0);\n\n return `${filter.name} - ${count}`;\n }\n\n return `${filter.name} - ${filterState.selection.length}`;\n }\n\n if (filter.type === 'rating') {\n if (!filterState.selection.length)\n return filter.name;\n\n const first = ArrayHelper.first(filterState.selection) as Rating;\n const last = ArrayHelper.last(filterState.selection) as Rating;\n\n if (filterState.selection.length === 1)\n return `${filter.name}: ${first.code}`;\n\n return `${filter.name}: ${first.code} to ${last.code}`;\n }\n },\n\n buildFrontendFilterParams(queryParams: HashObject, filterStates: Array<FilterPayloadType>): HashObject {\n const updatedParams = { ...queryParams };\n\n filterStates.forEach(filterState => {\n if (!filterState?.filter)\n return;\n\n const { id: param, type } = filterState.filter;\n const { active, selection } = filterState.state;\n\n switch (type) {\n case 'switch':\n updatedParams[param] = active ? 'true' : '';\n break;\n\n case 'radio':\n case 'dropdown':\n const isDefault =\n filterState.state.selection?.length === 1 && ArrayHelper.first(filterState.state.selection)?.default;\n\n updatedParams[param] = (filterState.state.selection.length && !isDefault) ? ArrayHelper.first(filterState.state.selection).id : '';\n break;\n\n case 'nested-checkbox':\n updatedParams[param] = active ? selection.map(option => option.id) : null;\n const { secondaryId: secondaryParam } = filterState.filter;\n\n if (secondaryParam) {\n // FlatMap\n updatedParams[secondaryParam] = [].concat(...selection.map(s => s.secondLayerSelection.map(o => o.id)));\n }\n\n break;\n\n case 'checkbox':\n case 'grouped-checkbox':\n if (!active) {\n updatedParams[param] = null;\n break;\n }\n\n const options = [];\n for (const option of selection) {\n const ids = option.id.toString().split(':');\n if (ids.length > 1) {\n // When an option has more than one id\n // e.g. An topic option can used by many presentations\n for (const id of ids) {\n options.push(id);\n }\n } else {\n options.push(option.id);\n }\n }\n\n updatedParams[param] = options;\n break;\n\n case 'tag':\n updatedParams[param] = active ? selection.map(option => option.id) : null;\n break;\n\n case 'rating':\n updatedParams[param] = active ? RatingFilterHelper.getFrontendParamValue(selection as Rating[]) : null;\n break;\n\n case 'button':\n updatedParams[param] = active ? 'true' : '';\n break;\n }\n\n if (!updatedParams[param]) // If the param is empty, delete it\n delete updatedParams[param];\n });\n\n return ObjectHelper.omit(updatedParams, ['cursor']);\n },\n\n buildBackendFilterParams(\n queryParams: HashObject,\n ratings: Rating[] = [],\n presentationIds: string[],\n isLearner: boolean,\n libraries: Library[],\n streamableLibraryId?: string\n ): HashObject {\n const defaultParams: HashObject = isLearner ? {\n ['filters.presentation']: presentationIds,\n isLearner\n } : {};\n\n return Object.keys(queryParams).reduce((acc: HashObject, paramName: FilterIds) => {\n const values = queryParams[paramName];\n\n if ((Array.isArray(values) && !values.length) || !values)\n return acc;\n\n if (!FilterWhitelist[paramName])\n return acc;\n\n if (paramName === 'rating') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = RatingFilterHelper.getBackendParamValue(values, ratings);\n return acc;\n }\n\n if (paramName === 'productionYear') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = ProductionYearFilterHelper.getBackendParamValue(values);\n return acc;\n }\n\n if (paramName === 'duration') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = DurationFilterHelper.getBackendParamValue(values);\n return acc;\n }\n\n if (paramName === 'moviesAndTv') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}curationTag`] = CurationTag.MOVIES_AND_TV;\n return acc;\n }\n\n if (paramName === 'source') {\n return {\n ...acc,\n ...SourceFilterHelper.getBackendParamValue(values, libraries, streamableLibraryId)\n };\n }\n\n if (paramName === 'scopeId') {\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}partnerProfile`] = [values];\n return acc;\n }\n\n acc[`${FilterConstants.FILTER_PARAM_PREFIX}${paramName}`] = values;\n\n return acc;\n }, defaultParams);\n },\n\n getAppliedIndices(\n queryParams: HashObject = {},\n _hasNewSearch: boolean = false,\n _hasPartnerProfiles: boolean = false\n ): SearchIndices[] {\n const { type: indices } = queryParams;\n\n const validIndices = getValidIndices({ hasPartnerProfiles: _hasPartnerProfiles });\n \n const newIndices: SearchIndices[] = ['category'];\n\n function validateIndices(indice: SearchIndices): boolean {\n if (_hasNewSearch) {\n return validIndices[indice];\n }\n\n return !newIndices.includes(indice) && validIndices[indice];\n }\n\n if (indices) {\n if (!Array.isArray(indices))\n return [indices].filter(validateIndices);\n\n if (indices.length)\n return indices.filter(validateIndices);\n }\n\n const extraIndices: SearchIndices[] = [];\n if (_hasNewSearch)\n extraIndices.push(...newIndices);\n \n if (queryParams.source)\n return [ 'video', 'clip', 'interactive', ...extraIndices ];\n\n if (_hasPartnerProfiles)\n return [ 'series', 'video', 'playlist', 'classification', 'clip', 'interactive', 'partner_profile', ...extraIndices ];\n\n return [ 'series', 'video', 'playlist', 'classification', 'clip', 'interactive', 'company', ...extraIndices ];\n },\n\n applyFilter(\n filters: Array<SearchFilter>,\n currentFilterState: FilterState | FilterStateHash,\n draftState: DraftState,\n baseAppLink: Core.AppLink\n ): void {\n if (ObjectHelper.isEqual(currentFilterState, draftState))\n return;\n\n const filterIds = Object.keys(draftState) as FilterIds[];\n\n const payload: Array<FilterPayloadType> = filterIds.map(filterId => {\n const filter = filters.find(f => f.id === filterId);\n const draftFilterState = draftState[filterId];\n\n const isDefaultValue =\n draftFilterState.selection?.length === 1 && ArrayHelper.first(draftFilterState.selection)?.default;\n\n return {\n filter,\n state: {\n active: draftFilterState.active && !isDefaultValue,\n selection: draftFilterState.selection\n }\n };\n });\n\n const currentQueryParams = Core.LocationUtils.GetQuery();\n Core.AppLinkHelper.trigger({\n ...baseAppLink,\n params: FilterHelper.buildFrontendFilterParams(currentQueryParams, payload)\n }, { replace: true });\n },\n\n mixinDisabledFields(\n state: FilterStateHash,\n indices: SearchIndices[],\n mainFilters: SearchFilter[],\n moreFilters?: MoreFilters\n ): MixinDisableFieldsFn {\n let allFilters = [ ...mainFilters, ...(moreFilters?.filters ?? []) ];\n\n // Iterate through each filter, and disable them if they should be disabled\n allFilters = disableFilters(state, allFilters, indices);\n\n // Iterate through each filter option, and disable them if they should be disabled\n allFilters = disableFilterOptions(state, allFilters);\n\n const response: MixinDisableFieldsFn = {\n mainFilters: allFilters.filter(filter => mainFilters.find(f => f.id === filter.id))\n };\n\n if (moreFilters?.filters) {\n response.moreFilters = {\n ...moreFilters,\n filters: allFilters.filter(filter => moreFilters.filters.find(f => f.id === filter.id))\n };\n }\n\n return response;\n },\n\n logFilterEvent(\n mainFilters: SearchFilter[],\n moreFilters: MoreFilters,\n state: FilterStateHash,\n query: string,\n analyticsOptions: AnalyticsOptions\n ): void {\n const analyticsFilterObjects: AnalyticsFilterHash[] = [];\n\n mainFilters?.forEach(f => {\n const filterState = state[f.id];\n\n if (filterState.active) {\n analyticsFilterObjects.push({\n type: f.id,\n selection: filterState.selection\n });\n }\n });\n\n moreFilters?.filters?.forEach(f => {\n const filterState = state.moreFilters[f.id];\n\n if (filterState.active) {\n analyticsFilterObjects.push({\n type: f.id,\n selection: filterState.selection\n });\n }\n });\n\n if (!analyticsFilterObjects.length)\n analyticsOptions.descriptor = FilterDescriptor.Reset;\n\n AnalyticsHelper.logUserAction({\n query: query ?? '',\n filters: analyticsFilterObjects\n }, AnalyticsHelper.mergeOptions(analyticsOptions, {\n workflowPhase: WorkflowPhase.Complete,\n actionType: UserAction.Filter\n }));\n },\n\n /**\n * Helpers below this comment return hard coded filter options for a particular filter.\n * If you are adding a new filter with hard coded options, add a new function here.\n */\n getObjectTypeOptions(\n inaccessibleIndices: SearchIndices[] = [],\n _hasNewSearch: boolean,\n _hasPartnerProfiles: boolean\n ): FilterOption<SearchIndices>[] {\n if (_hasNewSearch) {\n const options: FilterOption<SearchIndices>[] = [\n {\n id: 'video',\n name: getPhrase('videos'),\n group: getPhrase('videoTypes')\n },\n {\n id: 'interactive',\n name: getPhrase('interactives'),\n group: getPhrase('videoTypes')\n },\n {\n id: 'clip',\n name: getPhrase('clips'),\n group: getPhrase('videoTypes')\n },\n {\n id: 'classification',\n name: getPhrase('topics'),\n group: getPhrase('collections')\n },\n {\n id: 'series',\n name: getPhrase('series'),\n group: getPhrase('collections')\n },\n {\n id: 'playlist',\n name: getPhrase('playlists'),\n group: getPhrase('collections')\n },\n {\n id: 'category',\n name: getPhrase('category'),\n group: getPhrase('collections')\n }\n ];\n \n if (_hasPartnerProfiles) {\n options.push({\n id: 'partner_profile',\n name: getPhrase('channels'),\n group: getPhrase('collections')\n });\n }\n \n return options.filter(opt => !inaccessibleIndices.find(i => i === opt.id)) as FilterOption<SearchIndices>[];\n }\n\n return [\n {\n id: 'classification',\n name: getPhrase('topics')\n },\n {\n id: 'playlist',\n name: getPhrase('playlists')\n },\n {\n id: 'series',\n name: getPhrase('series')\n },\n {\n id: 'video',\n name: getPhrase('videos')\n },\n {\n id: 'clip',\n name: getPhrase('clips')\n },\n {\n id: 'interactive',\n name: getPhrase('interactives')\n }\n ].filter(opt => !inaccessibleIndices.find(i => i === opt.id)) as FilterOption<SearchIndices>[];\n },\n\n /**\n * Loops through each option on the \"object type\" filter, and determines whether\n * they should be disabled based on the currently active filters\n */\n getIsObjectTypeOptionDisabled(\n options: FilterOption<SearchIndices>[],\n filters: SearchFilter[],\n state: FilterStateHash\n ): FilterOption<SearchIndices>[] {\n return options.map(option => {\n let isDisabled = false;\n\n filters.forEach(filter => {\n if (isDisabled)\n return;\n\n const filterState = state[filter.id] || state.moreFilters[filter.id];\n\n if (!filterState?.active || !filter.compatibleIndices?.length)\n return;\n\n if (!filter.compatibleIndices.find(i => option.id === i))\n isDisabled = true;\n });\n\n return {\n ...option,\n disabled: isDisabled\n };\n });\n },\n\n getNameSortOptions(): FilterOption[] {\n return [\n {\n id: 'newest',\n name: getPhrase('newest')\n },\n {\n id: 'oldest',\n name: getPhrase('oldest')\n },\n {\n id: 'first-name-atoz',\n name: getPhrase('firstNameAToZ')\n },\n {\n id: 'first-name-ztoa',\n name: getPhrase('firstNameZToA')\n },\n {\n id: 'surname-atoz',\n name: getPhrase('surnameAToZ')\n },\n {\n id: 'surname-ztoa',\n name: getPhrase('surnameZToA')\n }\n ];\n },\n\n getYearGroupOptions(yearGroups: YearGroup[]): FilterOption[] {\n if (!yearGroups?.length)\n return [];\n\n return yearGroups.map(y => ({\n id: y.value.toString(),\n name: y.name\n }));\n },\n\n getStatusOptions(): FilterOption[] {\n return [\n {\n id: 'active',\n name: getPhrase('active')\n },\n {\n id: 'deactivated',\n name: getPhrase('deactivated')\n },\n {\n id: 'pending',\n name: getPhrase('pending')\n }\n ];\n },\n\n getJobStatusOptions(): FilterOption[] {\n return [\n {\n id: 'completed',\n name: getPhrase('completed')\n },\n {\n id: 'failed',\n name: getPhrase('errored')\n },\n {\n id: 'inProgress',\n name: getPhrase('inProgress')\n }\n ];\n },\n\n getTvFieldsOptions(): FilterOption[] {\n return [\n {\n id: '0',\n name: getPhrase('allFields'),\n default: true\n },\n {\n id: '1',\n name: getPhrase('titleDescriptionField')\n },\n {\n id: '2',\n name: getPhrase('captionsField')\n }\n ];\n },\n\n getTvChannelOptions(channels: BaseObject[]): FilterOption[] {\n if (!channels?.length)\n return [];\n\n return channels.map(channel => ({\n id: channel.name,\n name: channel.name\n }));\n },\n\n getTvDateBroadcastOptions(): FilterOption[] {\n return [\n {\n id: 'any-time',\n name: getPhrase('anyTime'),\n default: true\n },\n {\n id: 'yesterday',\n name: getPhrase('yesterday')\n },\n {\n id: 'last-week',\n name: getPhrase('lastWeek')\n },\n {\n id: 'last-2-weeks',\n name: getPhrase('last2Weeks')\n }\n ];\n },\n\n getCustomerStatusOptions(): FilterOption[] {\n return [\n {\n id: CustomerStatus.Unclassified.toString(),\n name: CustomerStatusString.Unclassified\n },\n {\n id: CustomerStatus.Active.toString(),\n name: CustomerStatusString.Active\n },\n {\n id: CustomerStatus.Prospect.toString(),\n name: CustomerStatusString.Prospect\n },\n {\n id: CustomerStatus.LostCustomer.toString(),\n name: CustomerStatusString.LostCustomer\n },\n {\n id: CustomerStatus.Disabled.toString(),\n name: CustomerStatusString.Disabled\n },\n {\n id: CustomerStatus.Other.toString(),\n name: CustomerStatusString.Other\n }\n ];\n },\n\n getCustomerTypeOptions(): FilterOption[] {\n return [\n {\n id: CustomerType.Unclassified.toString(),\n name: CustomerTypeString.Unclassified\n },\n {\n id: CustomerType.Primary.toString(),\n name: CustomerTypeString.Primary\n },\n {\n id: CustomerType.Secondary.toString(),\n name: CustomerTypeString.Secondary\n },\n {\n id: CustomerType.K12.toString(),\n name: CustomerTypeString.K12\n },\n {\n id: CustomerType.Tertiary.toString(),\n name: CustomerTypeString.Tertiary\n },\n {\n id: CustomerType.NonEducational.toString(),\n name: CustomerTypeString.NonEducational\n },\n {\n id: CustomerType.Partners.toString(),\n name: CustomerTypeString.Partners\n },\n {\n id: CustomerType.Internal.toString(),\n name: CustomerTypeString.Internal\n },\n {\n id: CustomerType.Other.toString(),\n name: CustomerTypeString.Other\n },\n {\n id: CustomerType.ClickView.toString(),\n name: CustomerTypeString.ClickView\n },\n {\n id: CustomerType.System.toString(),\n name: CustomerTypeString.System\n }\n ];\n },\n \n getCategoriesOptions(categories: MasterNestedObject<Library>[]): FilterOption[] {\n if (!categories?.length)\n return [];\n\n // TODO: Custom nested checkbox\n return categories.map(category => {\n return {\n id: category.data.id,\n name: category.data.name\n // secondLayerOptions: category.children.map(\n // nestedCategory => ({ id: nestedCategory.data.id, name: nestedCategory.data.name })\n // )\n };\n });\n },\n\n getSpecialEventTypeOptions(): FilterOption[] {\n return [\n {\n id: SpecialEventType.BreakingNews,\n name: SpecialEventTypeLabelMap[SpecialEventType.BreakingNews]\n },\n {\n id: SpecialEventType.SportingEvent,\n name: SpecialEventTypeLabelMap[SpecialEventType.SportingEvent]\n },\n {\n id: SpecialEventType.Observance,\n name: SpecialEventTypeLabelMap[SpecialEventType.Observance]\n },\n {\n id: SpecialEventType.NaturalDisaster,\n name: SpecialEventTypeLabelMap[SpecialEventType.NaturalDisaster]\n },\n {\n id: SpecialEventType.HistoricalEvent,\n name: SpecialEventTypeLabelMap[SpecialEventType.HistoricalEvent]\n },\n {\n id: SpecialEventType.Holiday,\n name: SpecialEventTypeLabelMap[SpecialEventType.Holiday]\n },\n {\n id: SpecialEventType.Informal,\n name: SpecialEventTypeLabelMap[SpecialEventType.Informal]\n },\n {\n id: SpecialEventType.ReligiousEvent,\n name: SpecialEventTypeLabelMap[SpecialEventType.ReligiousEvent]\n },\n {\n id: SpecialEventType.Other,\n name: SpecialEventTypeLabelMap[SpecialEventType.Other]\n }\n ];\n }\n};\n\n// This allows us to determine which filters should be applied based on the query params set on first load\nfunction getFilterSelectionsFromQueryParams(\n queryParams: HashObject,\n filters: SearchFilter[] = [],\n filterId: FilterIds\n): FilterOption[] {\n const filter = filters.find(f => f.id === filterId);\n\n if (!filter)\n return [];\n\n if (!queryParams[filterId])\n return filter.options?.filter(option => option.default) ?? [];\n\n if (filterId === 'rating')\n return RatingFilterHelper.deriveInitialRatingFilterStateFromQueryParams(queryParams[filterId], filter);\n\n let selections = queryParams[filterId];\n\n if (!Array.isArray(selections))\n selections = [selections];\n\n if (filterId === 'classification') {\n return ClassificationFilterHelper.deriveInitialClassificationFilterStateFromQueryParams(filter, selections);\n }\n\n if (filterId === 'presentation') {\n return PresentationFilterHelper.\n deriveInitialPresentationFilterStateFromQueryParams(filter.options, selections, queryParams);\n }\n\n return getSelectedOptions(filter.options, selections);\n}\n\nexport function getSelectedOptions(options: FilterOption[] | undefined, selections: any): any[] {\n if (!Array.isArray(selections))\n selections = [selections];\n\n return options?.filter(option => {\n return selections.find((id: number | string) => id.toString() === option.id.toString());\n }) ?? [];\n}\n\n/**\n * This basically iterates through every filter, and works out if that filter should be disabled.\n * This is based on:\n * - If the filter is compatible with any of the currently applied search indices\n * - If the filter is compatible with any of the filter indices that are compatible with any of the active filters\n */\nfunction disableFilters(state: FilterStateHash, filters: SearchFilter[], indices: SearchIndices[]): SearchFilter[] {\n // Convert the currently applied search indices into a hashmap\n const appliedIndices = indices.reduce((acc: HashObject, index) => {\n acc[index] = true;\n return acc;\n }, {});\n\n return filters.map(filter => {\n if (!filter.compatibleIndices?.length)\n return filter;\n\n // If none of the applied indices works with the filter, it should be disabled.\n // For example, if the user filters by \"playlists\", the \"has resources\" filter will be disabled.\n if (!filter.compatibleIndices.find(i => appliedIndices[i])) {\n return {\n ...filter,\n disabled: true\n };\n }\n \n // Get all currently active filters\n const activeFilterIds = Object.keys(state).filter((filterId: keyof typeof state) => {\n const filterState = state[filterId];\n\n if (!('active' in filterState))\n return false;\n\n return filterState.active;\n });\n\n let shouldDisableFilter = false;\n\n activeFilterIds.forEach(activeFilterId => {\n if (shouldDisableFilter)\n return;\n\n const activeFilter = filters.find(f => f.id === activeFilterId);\n\n if (!activeFilter.compatibleIndices?.length)\n return;\n\n const activeFilterIndices = activeFilter.compatibleIndices.reduce((acc: HashObject, index) => {\n acc[index] = true;\n return acc;\n }, {});\n\n /**\n * Check if the active filter's indices are compatible with the current filter's indices.\n * For example, if the \"has resources\" filter is active, then all filters that are incompatible\n * with videos will be disabled.\n */\n if (!filter.compatibleIndices.find(i => activeFilterIndices[i]))\n shouldDisableFilter = true;\n });\n\n return {\n ...filter,\n disabled: shouldDisableFilter\n };\n });\n}\n\n/**\n * This will disable particular option on a filter if they are incompatible with the currently\n * active filters.\n *\n * For example, if we apply the \"rating\" filter, then the \"playlist\" and \"classification\" options\n * on the \"ObjectTypes\" filter will be disabled, as we cannot filter by those options _and_ by rating\n * at the same time.\n */\nfunction disableFilterOptions(state: FilterStateHash, filters: SearchFilter[]): SearchFilter[] {\n return filters.map(filter => {\n if (!FunctionHelper.isFunction(filter.disableOptions))\n return filter;\n\n // Only filters that have a `disableOptions` function will run here.\n const options = filter.disableOptions(filter.options, filters, state);\n\n return {\n ...filter,\n options\n };\n });\n}\n",":local {\n .hideCaret::after {\n display: none;\n }\n\n .filterMenu {\n min-width: 10rem;\n width: max-content;\n\n &.twoColumnsWidth {\n max-width: 35rem;\n \n @media screen and (max-width: #{map-get($grid-breakpoints, md) - 1px}) {\n max-width: 20rem;\n }\n }\n\n &.nestedCheckboxesWidth {\n min-width: 12rem;\n }\n\n &.switchWidth {\n max-width: 15rem;\n }\n }\n\n .moreFiltersWidth {\n width: 25rem;\n max-width: calc(100vw - map-get($spacers, 4));\n }\n\n // Icon positioning adjustments to make it look nicer\n .svgContainer {\n margin-top: 0.05rem;\n margin-right: 0.2rem;\n margin-left: -0.2rem;\n }\n}\n","import * as React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { FilterActions } from 'libs/shared/apps/search/components/filter-actions/FilterActions';\nimport { SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterState } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\n\nimport styles from './filter-button.module.scss';\n\n/**\n * If your filter requires some customisations to the default width, add a use case here.\n */\nfunction getCustomWidthClass(filter: SearchFilter): string {\n if (FilterHelper.displayTwoColumns(filter))\n return styles.twoColumnsWidth;\n\n // Some classifications has long names, so we make them wider\n if (filter.id === 'classification')\n return styles.classificationWidth;\n \n if (FilterHelper.displayTwoLayers(filter))\n return styles.nestedCheckboxesWidth;\n\n if (filter.type === 'switch')\n return styles.switchWidth;\n\n return '';\n}\n\nFilterButton.defaultProps = {\n hideCaret: true\n};\n\ninterface FilterButtonProps {\n filter: SearchFilter;\n hideCaret?: boolean;\n}\n\nexport function FilterButton(props: FilterButtonProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n const currentFilterState = state[props.filter.id];\n\n const isDropdownFilter = props.filter.type === 'dropdown';\n\n const [ label, setLabel ] = React.useState(props.filter.name);\n const [ showDropdown, setShowDropdown ] = React.useState(false);\n const [ draftState, setDraftState ] = React.useState<FilterState>(currentFilterState);\n\n React.useEffect(() => {\n setLabel(FilterHelper.getLabel(props.filter, currentFilterState));\n setDraftState(currentFilterState);\n }, [ props.filter, currentFilterState?.selection ]);\n\n function onSelectItem(state: FilterState): void {\n setDraftState(state);\n\n if (isDropdownFilter)\n applyFilter(state);\n }\n\n function onClickReset(): void {\n const defaultOption = props.filter.options?.find(o => o.default);\n\n setDraftState({\n active: false,\n selection: defaultOption ? [defaultOption] : []\n });\n }\n\n function onClickApply(): void {\n applyFilter();\n setShowDropdown(false);\n }\n\n function applyFilter(newState: FilterState = draftState): void {\n FilterHelper.applyFilter(\n [props.filter],\n currentFilterState,\n { [props.filter.id]: newState },\n state.appLink\n );\n }\n\n function onToggleDropdown(isShowing: boolean): void {\n setShowDropdown(isShowing);\n\n if (isShowing || isDropdownFilter)\n return;\n\n // Apply the filter if the dropdown has been closed\n applyFilter();\n }\n\n const FilterComponent = React.useMemo(() => {\n return props.filter.customComponent ?\n props.filter.customComponent :\n FilterHelper.mapTypeToComponent(props.filter.type);\n }, [props.filter.type]);\n\n const baseClass = `fw-semibold mx-1 btn d-flex align-items-center`;\n const caretClass = props.hideCaret && !isDropdownFilter ? styles.hideCaret : '';\n const customWidthClass = getCustomWidthClass(props.filter);\n\n if (props.filter.type === 'button')\n return (\n <FilterComponent\n filter={props.filter}\n draftState={draftState}\n setDraftState={onSelectItem}\n />\n );\n\n return (\n <Dropdown onToggle={onToggleDropdown} show={showDropdown}>\n <Dropdown.Toggle\n id={`filterButton-${props.filter.id}`}\n className={`${baseClass} ${caretClass}`}\n variant={(currentFilterState.active && !isDropdownFilter) ? 'dark' : 'outline-dark'}\n disabled={props.filter.disabled}\n >\n {!!props.filter.icon && (\n <div className={styles.svgContainer}>\n <SvgContainer svg={props.filter.icon} />\n </div>\n )}\n {props.filter.labelPrefix} {label}\n </Dropdown.Toggle>\n\n <Dropdown.Menu>\n <div className={`mx-1 ${styles.filterMenu} ${customWidthClass} ${!isDropdownFilter ? 'px-2 py-1' : ''}`}>\n <FilterComponent\n filter={props.filter}\n draftState={draftState}\n setDraftState={onSelectItem}\n />\n\n {(!isDropdownFilter && !props.filter.disabled) && (\n <FilterActions\n active={draftState.active}\n onClickReset={onClickReset}\n onClickApply={onClickApply}\n />\n )}\n </div>\n </Dropdown.Menu>\n </Dropdown>\n );\n}\n","import { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nexport const StateHelper = {\n /**\n * Helper function to get the setState function for an individual key in a state object.\n * \n * @param setState React setState action\n * @param key Property within the state object we're updating\n * @param callback Optional callback to modify data before setting state. Uses identity fn by default.\n * \n * @returns Newly updated state object\n */\n getSetStateByKey<T extends HashObject>(\n setState: React.Dispatch<React.SetStateAction<T>>,\n key: keyof T,\n callback?: (data: any, state?: T) => T[keyof T]\n ): (data: any) => void {\n return (data: any) => setState(state => {\n const fn = FunctionHelper.isFunction(callback) ? callback : FunctionHelper.useIdentity<T>();\n return { ...state, [key]: fn(data, state) };\n });\n }\n};\n","import * as React from 'react';\nimport { Dropdown } from 'react-bootstrap';\n\nimport { FilterActions } from 'libs/shared/apps/search/components/filter-actions/FilterActions';\nimport { FilterIds, MoreFilters } from 'libs/shared/apps/search/interfaces';\nimport { DraftState, FilterContext, FilterStateHash } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { StateHelper } from 'libs/shared/utils/StateHelper';\n\nimport styles from './filter-button.module.scss';\n\nfunction getTotalActiveFilters(currentState: FilterStateHash): number {\n const total = Object.keys(currentState).reduce((acc: number, key: FilterIds) => {\n return currentState[key].active ?\n acc + 1 :\n acc;\n }, 0);\n\n return total;\n}\n\ninterface MoreFiltersButtonProps {\n filter: MoreFilters;\n}\n\nexport function MoreFiltersButton(props: MoreFiltersButtonProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n const currentFilterState = state.moreFilters;\n\n const [ label, setLabel ] = React.useState(props.filter.name);\n const [ showDropdown, setShowDropdown ] = React.useState(false);\n const [ draftState, setDraftState ] = React.useState<DraftState>(currentFilterState);\n const [ totalActiveFilters, setTotalActiveFilters ] = React.useState(getTotalActiveFilters(currentFilterState));\n\n const currentFilterStateKey = Object.keys(currentFilterState).map((id: FilterIds) => {\n return `${id}:${currentFilterState[id].active}`;\n }).join('-');\n\n React.useEffect(() => {\n setDraftState(currentFilterState);\n setTotalActiveFilters(getTotalActiveFilters(currentFilterState));\n }, [ props.filter, currentFilterStateKey ]);\n\n React.useEffect(() => {\n setLabel(totalActiveFilters ? `${props.filter.name} - ${totalActiveFilters}` : props.filter.name);\n }, [totalActiveFilters]);\n\n function onClickReset(): void {\n const filterIds = Object.keys(currentFilterState) as FilterIds[];\n\n const newState = filterIds.reduce((acc: DraftState, filterId) => {\n const filter = props.filter.filters.find(f => f.id === filterId);\n const defaultOption = filter.options?.find(o => o.default);\n\n acc[filterId] = {\n active: false,\n selection: defaultOption ? [defaultOption] : []\n };\n\n return acc;\n }, {});\n\n setDraftState(newState);\n }\n\n function onClickApply(): void {\n applyFilter();\n setShowDropdown(false);\n }\n\n function onToggleDropdown(isShowing: boolean): void {\n setShowDropdown(isShowing);\n\n if (isShowing)\n return;\n\n // Apply the filter if the dropdown has been closed\n applyFilter();\n }\n\n function applyFilter(): void {\n FilterHelper.applyFilter(\n props.filter.filters,\n currentFilterState,\n draftState,\n state.appLink\n );\n }\n\n const baseClass = `fw-semibold ${styles.hideCaret} mx-1 btn`;\n\n return (\n <Dropdown onToggle={onToggleDropdown} show={showDropdown}>\n <Dropdown.Toggle id={props.filter.id} className={baseClass} variant={totalActiveFilters ? 'dark' : 'outline-dark'}>\n {label}\n </Dropdown.Toggle>\n\n <Dropdown.Menu onClick={(e: React.MouseEvent) => e.stopPropagation()}>\n <div className={`mx-1 ${styles.moreFiltersWidth} ${props.filter.type !== 'dropdown' ? 'px-2 py-1' : ''}`}>\n {props.filter.filters.map(filter => {\n const FilterComponent = filter.customComponent ?\n filter.customComponent :\n FilterHelper.mapTypeToComponent(filter.type);\n\n return (\n <fieldset key={filter.id}>\n <FilterComponent\n filter={filter}\n draftState={draftState[filter.id]}\n setDraftState={StateHelper.getSetStateByKey(setDraftState, filter.id)}\n isOnMoreFilters\n />\n </fieldset>\n );\n })}\n\n <FilterActions\n active={!!Object.keys(draftState).find((key: FilterIds) => draftState[key].active)}\n onClickReset={onClickReset}\n onClickApply={onClickApply}\n />\n </div>\n </Dropdown.Menu>\n </Dropdown>\n );\n}\n","import React from 'react';\n\nimport styles from './tags.module.scss';\n\ninterface PartialTagItemProps {\n tagClass?: string;\n}\n\nexport const PartialTagItem = React.memo(function({ tagClass = '' }: PartialTagItemProps): JSX.Element {\n const classNames = `partial-loading-background d-inline-block rounded-pill py-1 px-2 mb-1 me-1 text-nowrap ${tagClass} ${styles.partialTag}`;\n\n return (\n <div className='mt-1'>\n <span className={classNames}>&nbsp;</span>\n </div>\n );\n});\n","import React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { DynamicWidgetState } from 'libs/shared/components/widgets/dynamic-widget';\nimport { FixedWidgetState } from 'libs/shared/components/widgets/fixed-widget';\n\n// Sync with transition time in SlidingListContainer.tsx\nconst SLIDER_ANIMATION_TIME = 400;\n\ntype FixedWidgetKeyboardOptions = {\n type: 'fixed',\n state: FixedWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery?: never\n};\n\ntype DynamicWidgetKeyboardOptions = {\n type: 'dynamic',\n state: DynamicWidgetState,\n containerRef: React.MutableRefObject<HTMLElement>,\n mediaQuery: string\n};\n\ntype UseWidgetKeyboard = FixedWidgetKeyboardOptions | DynamicWidgetKeyboardOptions;\n\nexport function useWidgetKeyboard(options: UseWidgetKeyboard) {\n const { type, state, containerRef, mediaQuery } = options;\n\n const [ isTabbing, setIsTabbing ] = React.useState(false);\n const [ dynamicAttributes, setDynamicAttributes ] = React.useState<HashObject>({});\n const [ focusedWidgetIndex, setFocusedWidgetIndex ] = React.useState(null);\n\n const isTouch = React.useMemo(() => UserAgentHelper.isTouchScreen(), []);\n\n /**\n * Get accessibility attributes for dynamic widget items\n * */\n React.useEffect(() => {\n if (type !== 'dynamic' || !containerRef.current || !(state as DynamicWidgetState).containerLeftPosition || isTouch) return;\n\n setTimeout(() => getDynamicAttributes(), SLIDER_ANIMATION_TIME + 50);\n }, [\n containerRef.current,\n mediaQuery,\n (state as DynamicWidgetState).offset,\n (state as DynamicWidgetState).containerLeftPosition\n ]);\n\n function getDynamicAttributes() {\n const dynamicWidgetState = state as DynamicWidgetState;\n\n if (!containerRef.current?.children)\n return;\n\n const focusableItems = Array.from(containerRef.current.children).reduce((acc, item) => {\n const rect = item?.getBoundingClientRect();\n\n /**\n * When any part of the widget item is visible it should be focusable,\n * otherwise prevent interaction and the slider should be the next focusable element\n * */\n const isItemVisable =\n rect.left < dynamicWidgetState.containerRightPosition &&\n rect.right > dynamicWidgetState.containerLeftPosition;\n\n return {\n ...acc,\n [item.id]: isItemVisable ?\n {\n 'aria-hidden': false\n } : {\n 'aria-hidden': true,\n 'inert': 'true'\n }\n };\n }, {});\n\n setDynamicAttributes(focusableItems);\n }\n\n /**\n * Get accessibility attributes for fixed widget items\n * */\n function getFixedAttributes(index?: number) {\n const fixedWidgetState = state as FixedWidgetState;\n\n const isItemVisible =\n isTouch ||\n index >= (fixedWidgetState.offset - fixedWidgetState.viewableItems) &&\n index < fixedWidgetState.offset;\n if (isItemVisible) {\n return {\n 'aria-hidden': false\n };\n }\n\n return {\n 'inert': 'true',\n 'aria-hidden': true\n };\n }\n\n /**\n * When the user is not signed in, there may be videos which are not focusable.\n * setTimeout is required because the transition time is 400ms\n */\n function focusNext() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let nextFocusableElement: HTMLElement = null;\n\n for (let i = (focusedWidgetIndex + 1); i < items.length; i++) {\n if (nextFocusableElement)\n break;\n\n nextFocusableElement = items[i].querySelector('a[tabindex=\"0\"]');\n }\n\n if (nextFocusableElement)\n nextFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function focusPrev() {\n setTimeout(() => {\n if (!containerRef.current)\n return;\n\n const items = containerRef.current.querySelectorAll('li[aria-hidden]');\n\n let prevFocusableElement: HTMLElement = null;\n for (let i = focusedWidgetIndex - 1; i >= 0; i--) {\n if (prevFocusableElement) break;\n\n const item = items[i];\n prevFocusableElement = item.querySelector('a[tabindex=\"0\"]');\n }\n\n if (prevFocusableElement)\n prevFocusableElement.focus();\n }, SLIDER_ANIMATION_TIME + 100);\n }\n\n function onFocusWidget(index: number) {\n if (document.querySelector('.user-is-tabbing')) {\n setIsTabbing(true);\n setFocusedWidgetIndex(index);\n }\n }\n\n function onBlurWidget() {\n if (!document.querySelector('.user-is-tabbing')) {\n setIsTabbing(false);\n setFocusedWidgetIndex(null);\n }\n }\n\n return {\n isTabbing,\n onFocusWidget,\n onBlurWidget,\n getFixedAttributes,\n dynamicAttributes,\n focusNext,\n focusPrev\n };\n}\n","export enum CssMeasurement {\n Percentage = '%',\n Pixels = 'px'\n}\n","import { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\n\nconst blankImage = new Image();\nblankImage.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=';\n\nexport const DragHelper = {\n // This removes the image that appears when you drag a draggable HTML element\n hideDragImage(event: React.DragEvent<HTMLElement>): void {\n if (!event.dataTransfer.setDragImage || !FunctionHelper.isFunction(event.dataTransfer.setDragImage))\n return;\n\n event.dataTransfer.setDragImage(blankImage, 0, 0);\n }\n};\n","import * as React from 'react';\n\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\n\nimport { CssMeasurement } from 'libs/shared/enums/CssMeasurement';\nimport { DragHelper } from 'libs/shared/utils/DragHelper';\n\nconst isTouchScreen = UserAgentHelper.isTouchScreen();\n\nconst getPositionStyling = (xPosition: number, measurement: CssMeasurement, dragPercentage?: number) => {\n // Used in situations where a touch screen user is dragging the `<FixedWidget />`\n if (measurement === CssMeasurement.Percentage && dragPercentage)\n xPosition = xPosition - dragPercentage;\n \n return {\n transform: `translate3d(${xPosition}${measurement}, 0px, 0px)`,\n // Sync with transition time in useWidgetKeyboard.ts\n transition: 'transform .4s ease-in-out'\n };\n};\n\ninterface SlidingListContainerProps extends React.PropsWithChildren<unknown> {\n position: number;\n positionType: CssMeasurement;\n\n onDrag?: (event: React.DragEvent<HTMLUListElement>) => void;\n onDragEnd?: () => void;\n\n onTouchMove?: (event: React.TouchEvent<HTMLUListElement>) => void;\n onTouchEnd?: () => void;\n\n percentageDragged?: number;\n}\n\nexport const SlidingListContainer = React.forwardRef((\n props: SlidingListContainerProps,\n ref: React.MutableRefObject<HTMLUListElement>\n): JSX.Element => {\n const { children, positionType, onDrag, onDragEnd, onTouchMove, onTouchEnd, percentageDragged, position = 0 } = props;\n\n function getEventListeners(): HashObject {\n const listenerProps: HashObject = {};\n\n if (onDrag && onDragEnd) {\n listenerProps.draggable = true;\n listenerProps.onDragEnd = onDragEnd;\n listenerProps.onDragStart = DragHelper.hideDragImage;\n listenerProps.onDragOver = onDrag;\n }\n\n if (onTouchMove && onTouchEnd && isTouchScreen) {\n listenerProps.onTouchMoveCapture = onTouchMove;\n listenerProps.onTouchEndCapture = onTouchEnd;\n }\n\n return listenerProps;\n }\n\n return (\n <ul\n className='list-unstyled d-flex flex-nowrap position-relative w-100 mb-0'\n style={getPositionStyling(position, positionType, percentageDragged)}\n ref={ref}\n {...getEventListeners()}\n >\n {children}\n </ul>\n );\n});\n","import React from 'react';\n\nexport function ChevronRightSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n d='M15.695 11.267c.407.41.407 1.056 0 1.466L9.79 18.696a1.046 1.046 0 0 1-1.474 0l-.01-.01a1.034 1.034 0 0 1 0-1.467L13.474 12l-5.17-5.22a1.034 1.034 0 0 1 0-1.465l.012-.011a1.046 1.046 0 0 1 1.474 0z'\n fill='currentColor'\n />\n </svg>\n );\n}\n",":local {\n $svg-shift: 0.1rem; // Even though the element is centered, the chevron SVGs appear slightly off-center. This corrects that.\n $title-text-height: .875rem;\n\n .buttonContainer {\n position: absolute;\n width: 100%;\n top: 0;\n pointer-events: none;\n }\n\n .left {\n left: -1rem;\n\n svg {\n transform: translateX(-$svg-shift);\n }\n }\n\n .right {\n right: -1rem;\n\n svg {\n transform: translateX($svg-shift);\n }\n }\n\n .button {\n position: absolute;\n background-color: $white;\n border-radius: $cv-svg-size-xlg * 0.5;\n cursor: pointer;\n pointer-events: auto;\n transform: translateY(-50%);\n z-index: 5;\n box-shadow: 0px 2px 4px 1px rgba(0, 0, 0, 0.3);\n height: $cv-svg-size-xlg;\n min-width: $cv-svg-size-xlg;\n display: flex;\n align-items: center;\n justify-content: center;\n\n transition: all .2s;\n\n .hoverText {\n display: none;\n transition: all .2s;\n }\n\n svg {\n color: $gray-700;\n }\n\n &:hover {\n @extend .buttonHover;\n }\n }\n\n .buttonHover {\n .hoverText ~ .chevron {\n margin-right: 0.4rem;\n }\n\n .hoverText {\n display: block;\n }\n\n svg,\n .hoverText {\n color: $gray-900;\n }\n }\n\n %backdrop {\n position: absolute;\n width: 2.5rem;\n height: 101%;\n z-index: 3;\n top: 50%;\n transform: translateY(-50%);\n }\n\n .gradientLeft {\n @extend %backdrop;\n left: -1.5rem;\n background-image: linear-gradient(to left, $cv-safe-transparent 0%, $white 70%);\n }\n\n .gradientRight {\n @extend %backdrop;\n right: -1.5rem;\n background-image: linear-gradient(to right, $cv-safe-transparent 0%, $white 70%);\n }\n\n .extendedClickableArea {\n @extend %backdrop;\n cursor: pointer;\n pointer-events: auto;\n background-color: $cv-safe-transparent;\n \n &.right {\n right: -1.5rem;\n }\n \n &.left {\n left: -1.5rem;\n }\n\n &:hover + .button {\n @extend .buttonHover\n }\n }\n\n .topPos {\n top: 50%;\n }\n}\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { FixedWidgetState } from 'libs/shared/components/widgets/fixed-widget';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { ChevronLeftSvg } from 'libs/shared/images/svg/arrows/ChevronLeftSvg';\nimport { ChevronRightSvg } from 'libs/shared/images/svg/arrows/ChevronRightSvg';\n\nimport styles from './widget-button.module.scss';\n\nconst namespace = 'shared.widgetButton';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport enum WidgetButtonDirection {\n Left,\n Right\n}\n\ninterface WidgetButtonProps {\n onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;\n direction: WidgetButtonDirection;\n hide: boolean;\n contents?: WidgetContents;\n useGradientBackdrop?: boolean;\n className?: string;\n hoverText?: string;\n hideExtendedClickableArea?: boolean;\n state?: FixedWidgetState;\n\n leftButtonClassName?: string;\n rightButtonClassName?: string;\n leftGradientClassName?: string;\n rightGradientClassName?: string;\n containerClassName?: string;\n}\n\nexport const WidgetButton = React.memo(function(props: WidgetButtonProps): JSX.Element {\n const isLeft = props.direction === WidgetButtonDirection.Left;\n\n const arrowSvg = isLeft ? ChevronLeftSvg : ChevronRightSvg;\n\n function getPositionClass(): string {\n let className = styles.topPos;\n \n // Left / Right\n if (isLeft)\n className += ` ${styles.left} ${props.leftButtonClassName}`;\n else\n className += ` ${styles.right} ${props.rightButtonClassName}`;\n \n return className;\n }\n\n function getStyle(): React.CSSProperties {\n if (props.state?.contents === 'videos')\n return { paddingBottom: (56.25 / props.state?.viewableItems) + '%' };\n\n return { height: '100%' };\n }\n\n if (props.hide)\n return <></>;\n\n return (\n <div className={`${styles.buttonContainer} ${props.containerClassName ? props.containerClassName : ''}`} style={getStyle()}>\n {props.useGradientBackdrop &&\n <div className={isLeft ? `${styles.gradientLeft} ${props.leftGradientClassName}` : `${styles.gradientRight} ${props.rightGradientClassName}`} />\n }\n\n {!props.hideExtendedClickableArea && (\n <button\n onClick={props.onClick}\n className={`${styles.extendedClickableArea} ${isLeft ? styles.left : styles.right}`}\n tabIndex={-1}\n />\n )}\n\n <button\n className={`${getPositionClass()} ${styles.button} ${props.className || ''}`}\n onClick={props.onClick}\n aria-label={isLeft ? getPhrase('previous') : getPhrase('next')}\n >\n {props.hoverText && (\n <span className={`ps-3 pe-2 ${styles.hoverText}`}>{props.hoverText}</span>\n )}\n <SvgContainer\n svg={arrowSvg}\n size={SvgContainerSize.Medium}\n className={`svg-container d-inline-block ${styles.chevron}`}\n />\n </button>\n </div>\n );\n});\n","export enum WidgetInteraction {\n Init = 'init',\n Next = 'next',\n Previous = 'previous',\n Resize = 'resize',\n Drag = 'drag',\n Update = 'update',\n JumpToIndex = 'jump-to-index'\n}\n","import * as React from 'react';\n\n/**\n * Hook function for listening to scroll events\n * @param onResize - gets called on resize.\n * @param onResizeEnd (optional) - gets called 100ms after the last resize event. Timer restarts everytime the callback\n * runs so that endCallback only fires after a stretch of resize events.\n * @param dependencies - values from the component (e.g. state, props and functions) that are used \n * inside the effect hook.\n */\nexport function useResizeListener(onResize: () => void, onResizeEnd?: () => void, dependencies: any[] = []): void {\n let resizeTimeout: number;\n\n const onResizeModified = () => {\n onResize();\n\n window.clearTimeout(resizeTimeout);\n resizeTimeout = window.setTimeout(onResizeEnd, 100);\n };\n\n React.useEffect(() => {\n window.addEventListener('resize', onResizeEnd ? onResizeModified : onResize);\n return () => window.removeEventListener('resize', onResizeEnd ? onResizeModified : onResize);\n }, [...dependencies]);\n}\n","import { ReducerActions } from 'libs/common/react/interfaces';\n\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { WidgetInteraction } from 'libs/shared/enums/WidgetInteraction';\nimport { SlidingListRefs } from 'libs/shared/interfaces/SlidingListRefs';\n\nimport { DynamicWidgetState } from './DynamicWidgetReducer';\n\ninterface WidgetSnapshot extends DynamicWidgetState {\n initialMouseX: number;\n}\n\n/**\n * Resize events\n */\nexport const getResizeHandler = (\n elementRefs: SlidingListRefs,\n dispatch: React.Dispatch<ReducerActions<WidgetInteraction>>,\n mediaQuery: MediaQueryStrings\n) => () => {\n if (elementRefs.container.current)\n elementRefs.container.current.style.transition = '';\n\n dispatch({\n type: WidgetInteraction.Resize,\n payload: {\n elementRefs,\n mediaQuery\n }\n });\n};\n\nexport const getResizeEndHandler = (containerRef: React.MutableRefObject<HTMLUListElement>) => () => {\n if (containerRef.current)\n containerRef.current.style.transition = 'transform .4s ease-in-out';\n};\n\nexport const getDragHandler = (\n containerRef: React.MutableRefObject<HTMLUListElement>,\n widgetState: DynamicWidgetState,\n dispatch: React.Dispatch<ReducerActions<WidgetInteraction>>,\n widgetSnapshot: WidgetSnapshot,\n setWidgetSnapshot: React.Dispatch<WidgetSnapshot>\n) => (event: React.DragEvent<HTMLUListElement>): void => {\n const mouseX = event.clientX;\n\n let snapshot = widgetSnapshot;\n\n if (!snapshot) {\n snapshot = { ...widgetState, initialMouseX: mouseX };\n setWidgetSnapshot(snapshot);\n containerRef.current.style.transition = '';\n }\n\n dispatch({\n type: WidgetInteraction.Drag,\n payload: {\n widgetSnapshot: snapshot,\n currentMouseX: mouseX\n }\n });\n};\n\nexport const getDragEndHandler = (\n containerRef: React.MutableRefObject<HTMLUListElement>,\n setWidgetSnapshot: React.Dispatch<WidgetSnapshot>\n) => () => {\n containerRef.current.style.transition = 'transform .4s ease-in-out';\n setWidgetSnapshot(null);\n};\n","import { ReducerActions } from 'libs/common/react/interfaces';\n\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { WidgetInteraction } from 'libs/shared/enums/WidgetInteraction';\nimport { SlidingListRefs } from 'libs/shared/interfaces/SlidingListRefs';\n\nexport interface DynamicWidgetState {\n /**\n * X-position argument for `translate3d()` to determine where the slider is positioned.\n */\n offset: number;\n\n /**\n * Left position of the slider container.\n * Set on `Init`, and updated on `Resize`.\n * Used for calculations on `Previous`, or for dragging to the right.\n */\n containerLeftPosition: number;\n\n /**\n * Right position of the slider container.\n * Set on Init, and updated on Resize.\n * Used for calculations on `Next`, or for dragging to the left.\n */\n containerRightPosition: number;\n\n /**\n * The position of the left edge of the very first element in the slider list.\n * Initially this will always be equal to `containerLeftPosition`.\n */\n firstElementPosition: number;\n\n /**\n * The position of the right edge of the very last element in the slider list.\n */\n lastElementPosition: number;\n\n /**\n * True when `firstElementPosition === containerLeftPosition`.\n */\n hideLeftButton: boolean;\n\n /**\n * True when `lastElementPositon === containerRightPosition`.\n */\n hideRightButton: boolean;\n\n /**\n * When clicking left or right, this number is the max distance in pixels that the slider.\n * will move.\n * Default 300.\n * Can only be set once on `Init` action.\n */\n maxSlideDistance: number;\n\n /**\n * This is calculated on `Init`, and is the lowest number the `offset` state can ever be.\n * This is needed for the `Drag` event, as the `Drag` event can only calculate whole numbers.\n * 99% of the time, the leftOffsetLimit is a very specific decimal number, so we calculate it\n * on `Init` and reference it on `Drag` events when necessary.\n */\n leftOffsetLimit: number;\n}\n\nfunction getMaxSlideDistance(mediaQuery: MediaQueryStrings): number {\n if (mediaQuery === MediaQueryStrings.XS)\n return 200;\n\n if (mediaQuery === MediaQueryStrings.SM || mediaQuery === MediaQueryStrings.MD)\n return 350;\n\n return 500;\n}\n\n/**\n * `null` values are initialized in the `Init` action. This is dispatched\n * later, because it uses JQuery elements that aren't immediately available\n * when `useReducer` is called.\n */\nexport const initialSliderState: DynamicWidgetState = {\n offset: 0,\n containerLeftPosition: null,\n containerRightPosition: null,\n firstElementPosition: null,\n lastElementPosition: null,\n hideLeftButton: true,\n hideRightButton: true,\n maxSlideDistance: 0,\n leftOffsetLimit: null\n};\n\ninterface InitPayload {\n elementRefs: SlidingListRefs;\n mediaQuery: MediaQueryStrings;\n}\n\nconst onInit = (payload: InitPayload): DynamicWidgetState => {\n const { container, lastElement } = payload.elementRefs;\n\n if (!container?.current || !lastElement?.current)\n return initialSliderState;\n\n const containerRect = container.current.getBoundingClientRect();\n const containerLeftPosition = containerRect.left;\n const containerRightPosition = containerRect.right;\n\n const firstElementPosition = containerLeftPosition;\n const lastElementPosition = lastElement.current.getBoundingClientRect().right;\n const leftOffsetLimit = containerRightPosition - lastElementPosition;\n\n return {\n ...initialSliderState,\n containerLeftPosition,\n containerRightPosition,\n firstElementPosition,\n lastElementPosition,\n hideRightButton: lastElementPosition < containerRightPosition,\n leftOffsetLimit,\n maxSlideDistance: getMaxSlideDistance(payload.mediaQuery)\n };\n};\n\ninterface ResizePayload {\n elementRefs: SlidingListRefs;\n mediaQuery: MediaQueryStrings;\n}\n\nconst onResize = (payload: ResizePayload): DynamicWidgetState => {\n const initialState = onInit({\n ...payload,\n ...payload.elementRefs\n });\n\n return {\n ...initialState,\n maxSlideDistance: getMaxSlideDistance(payload.mediaQuery)\n };\n};\n\nconst onNext = (prevState: DynamicWidgetState): Partial<DynamicWidgetState> => {\n const { firstElementPosition, lastElementPosition, maxSlideDistance, offset, containerRightPosition } = prevState;\n\n /**\n * The distance in pixels that the slider will move along the x-axis.\n * This will be the `maxSlideDistance` constant value, or if that value is too large we calculate\n * the remaining overflowing space and only slide by that amount.\n */\n const slideDistance = lastElementPosition - containerRightPosition >= maxSlideDistance ?\n maxSlideDistance :\n lastElementPosition - containerRightPosition;\n\n return {\n firstElementPosition: firstElementPosition - slideDistance,\n lastElementPosition: lastElementPosition - slideDistance,\n offset: offset - slideDistance,\n hideRightButton: lastElementPosition - slideDistance === containerRightPosition,\n hideLeftButton: false\n };\n};\n\nconst onPrevious = (prevState: DynamicWidgetState): Partial<DynamicWidgetState> => {\n const { containerLeftPosition, firstElementPosition, lastElementPosition, maxSlideDistance, offset } = prevState;\n\n const fullSlide = firstElementPosition + maxSlideDistance <= containerLeftPosition;\n const slideDistance = fullSlide ? maxSlideDistance : Math.abs(offset);\n\n return {\n firstElementPosition: firstElementPosition + slideDistance,\n lastElementPosition: lastElementPosition + slideDistance,\n offset: offset + slideDistance,\n hideLeftButton: !fullSlide || firstElementPosition + slideDistance === containerLeftPosition,\n hideRightButton: false\n };\n};\n\nconst onDrag = (prevState: DynamicWidgetState, payload: any): Partial<DynamicWidgetState> => {\n const { widgetSnapshot, currentMouseX } = payload;\n\n // Disable dragging if the slider isn't long enough\n if (widgetSnapshot.hideLeftButton && widgetSnapshot.hideRightButton)\n return {};\n\n // The distance from the initial `MouseDown` event x-coordinate, to the present x-coordinate\n const dragDistance = widgetSnapshot.initialMouseX - currentMouseX;\n\n let offset = widgetSnapshot.offset - dragDistance;\n let firstElementPosition = widgetSnapshot.firstElementPosition - dragDistance;\n let lastElementPosition = widgetSnapshot.lastElementPosition - dragDistance;\n let hideLeftButton = false;\n let hideRightButton = false;\n\n if (firstElementPosition > prevState.containerLeftPosition) {\n offset = 0;\n firstElementPosition = prevState.containerLeftPosition;\n lastElementPosition = prevState.lastElementPosition;\n hideLeftButton = true;\n }\n\n if (lastElementPosition <= prevState.containerRightPosition) {\n offset = prevState.leftOffsetLimit;\n firstElementPosition = prevState.containerLeftPosition - Math.abs(prevState.leftOffsetLimit);\n lastElementPosition = widgetSnapshot.containerRightPosition;\n hideRightButton = true;\n }\n\n return {\n offset,\n firstElementPosition,\n lastElementPosition,\n hideLeftButton,\n hideRightButton\n };\n};\n\nexport function DynamicWidgetReducer(\n prevState: DynamicWidgetState,\n action: ReducerActions<WidgetInteraction>\n): DynamicWidgetState {\n switch (action.type) {\n case WidgetInteraction.Init:\n return {\n ...prevState,\n ...onInit(action.payload)\n };\n\n case WidgetInteraction.Resize:\n return {\n ...prevState,\n ...onResize(action.payload)\n };\n\n case WidgetInteraction.Next:\n return {\n ...prevState,\n ...onNext(prevState)\n };\n\n case WidgetInteraction.Previous:\n return {\n ...prevState,\n ...onPrevious(prevState)\n };\n\n case WidgetInteraction.Drag:\n return {\n ...prevState,\n ...onDrag(prevState, action.payload)\n };\n\n default:\n return prevState;\n }\n}\n",":local {\n .itemSpacing {\n &:not(:last-child) {\n margin-right: map-get($spacers, 2);\n }\n }\n\n .header {\n z-index: 1;\n position: relative;\n }\n\n .mobileScroll {\n overflow-x: scroll;\n -ms-overflow-style: none;\n scrollbar-width: none;\n\n &::-webkit-scrollbar {\n display: none;\n }\n }\n\n .leftGradient {\n left: -2rem;\n }\n\n .leftGradientNoPadding {\n left: 0;\n }\n\n .leftButton {\n left: -1.3rem;\n }\n\n .leftButtonNoPadding {\n left: 0.1rem;\n }\n\n .rightGradient {\n right: -2rem;\n }\n\n .rightGradientNoPadding {\n right: 0;\n }\n\n .rightButton {\n right: -1.3rem;\n }\n\n .rightButtonNoPadding {\n right: 0.5rem;\n }\n}","import * as React from 'react';\n\nimport { FunctionHelper } from 'libs/common/backbone/utils/FunctionHelper';\nimport { UserAgentHelper } from 'libs/common/backbone/utils/UserAgentHelper';\nimport { Core } from 'libs/common/core';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { AnalyticsOptions, HashObject } from 'libs/analytics/interfaces';\n\nimport { WidgetHeader } from 'libs/shared/components/widgets/curated-widgets/components/header/WidgetHeader';\nimport { useWidgetKeyboard } from 'libs/shared/components/widgets/hooks/useWidgetKeyboard';\nimport { SlidingListContainer } from 'libs/shared/components/widgets/sliding-list/SlidingListContainer';\nimport { WidgetButton, WidgetButtonDirection } from 'libs/shared/components/widgets/widget-button/WidgetButton';\nimport { CssMeasurement } from 'libs/shared/enums/CssMeasurement';\nimport { WidgetInteraction } from 'libs/shared/enums/WidgetInteraction';\nimport { useGetMediaQueryString } from 'libs/shared/hooks/UseGetMediaQueryString';\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\nimport { BaseObject } from 'libs/shared/interfaces';\nimport { SlidingListRefs } from 'libs/shared/interfaces/SlidingListRefs';\nimport { PartialLoadingHelper, PartialLoadingOptions } from 'libs/shared/utils/PartialLoadingHelper';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { getDragEndHandler, getDragHandler, getResizeEndHandler, getResizeHandler } from './DynamicWidgetEventHandlers';\nimport { DynamicWidgetReducer, DynamicWidgetState, initialSliderState } from './DynamicWidgetReducer';\n\nimport styles from './dynamic-widget.module.scss';\n\ninterface WidgetSnapshot extends DynamicWidgetState {\n initialMouseX: number;\n}\n\ninterface StaticChild {\n position: 'start' | 'end';\n component: React.ElementType;\n}\n\ninterface DynamicWidgetProps {\n id?: string;\n childComponent: React.ElementType;\n childComponentProps?: any;\n partialLoadingComponent: React.ElementType;\n partialLoadingOptions?: PartialLoadingOptions;\n\n widgetDataDeps?: (any)[];\n getChildAppLink?: (data: any) => Core.AppLink;\n\n staticChildren?: StaticChild[];\n collection?: BaseObject[];\n fetch?: (...args: any[]) => any;\n lazyLoad?: boolean;\n\n heading?: string;\n headingAppLink?: Core.AppLink;\n description?: string;\n getSubtitle?: (data: any) => string;\n\n analyticsData?: HashObject;\n analyticsOptions?: AnalyticsOptions;\n\n getWidgetItemAnalyticsData?: (data: any) => HashObject;\n hideButtons?: boolean;\n childClassName?: string;\n // set to true if the widget get cut off by the container\n noNegativePadding?: boolean;\n}\n\nDynamicWidget.defaultProps = {\n heading: '',\n description: '',\n childComponentProps: {}\n};\n\nexport function DynamicWidget(props: DynamicWidgetProps): JSX.Element {\n const { childComponent: WidgetItemComponent, staticChildren, getWidgetItemAnalyticsData = () => {} } = props;\n\n const [ state, dispatch ] = React.useReducer(DynamicWidgetReducer, initialSliderState);\n\n // A snapshot of the widget state is captured on the very first `Drag` event as a point of reference\n const [ widgetSnapshot, setWidgetSnapshot ] = React.useState<WidgetSnapshot>(null);\n\n const elementRefs: SlidingListRefs = {\n container: React.useRef(null),\n firstElement: React.useRef(null),\n lastElement: React.useRef(null)\n };\n\n const mediaQuery = useGetMediaQueryString();\n const isTouchScreen = UserAgentHelper.isTabletOrMobile();\n \n const { dynamicAttributes, focusNext, focusPrev, onFocusWidget, onBlurWidget } = useWidgetKeyboard({ type: 'dynamic', state, containerRef: elementRefs.container, mediaQuery });\n\n useResizeListener(\n getResizeHandler(elementRefs, dispatch, mediaQuery),\n getResizeEndHandler(elementRefs.container),\n [mediaQuery]\n );\n\n const { ref, inView } = useLazyLoad({ prevent: !props.lazyLoad });\n\n let widgetData = props.collection;\n\n if (!props.collection && FunctionHelper.isFunction(props.fetch)) {\n const request = props.fetch(inView);\n widgetData = request.data;\n }\n\n /**\n * Once the widget data has been set, we can initialize the reducer. This is because\n * the reducer depends on the refs being set, but they don't get set until the markup has been loaded.\n */\n React.useEffect(() => {\n if (!widgetData || ObjectHelper.isEmpty(widgetData))\n return;\n\n dispatch({\n type: WidgetInteraction.Init,\n payload: {\n elementRefs,\n mediaQuery\n }\n });\n }, [widgetData]);\n\n function getWidgetItems(): JSX.Element {\n if (!widgetData)\n return;\n\n const firstChildren = staticChildren?.filter(child => child.position === 'start') ?? [];\n const lastChildren = staticChildren?.filter(child => child.position === 'end') ?? [];\n\n let items = widgetData.map((widgetItem, index) => {\n let itemRef: React.MutableRefObject<HTMLLIElement>;\n\n if (widgetItem === ArrayHelper.first(widgetData) && firstChildren?.length)\n itemRef = elementRefs.firstElement;\n\n if (widgetItem === ArrayHelper.last(widgetData) && !lastChildren?.length)\n itemRef = elementRefs.lastElement;\n\n const isLast = index + 1 === widgetData.length;\n\n return (\n <li\n id={widgetItem.id}\n key={widgetItem.id}\n ref={itemRef}\n onFocus={() => onFocusWidget(index)}\n onBlur={() => onBlurWidget()}\n className={`${styles.itemSpacing} ${props.childClassName || ''} ${(isLast && isTouchScreen) ? 'pe-4' : ''}`}\n {...dynamicAttributes[widgetItem.id]}\n >\n <WidgetItemComponent\n getChildAppLink={props.getChildAppLink}\n data={widgetItem}\n getSubtitle={props.getSubtitle}\n analyticsData={{\n itemIndex: index,\n ...props.analyticsData,\n ...getWidgetItemAnalyticsData(widgetItem)\n }}\n analyticsOptions={{ ...props?.analyticsOptions, ...WidgetHelper.getSliderItemAnalyticsOptions() }}\n {...props.childComponentProps}\n />\n </li>\n );\n });\n\n if (firstChildren.length) {\n items = [\n ...firstChildren.map((child, i) => {\n const Component = child.component;\n\n return (\n <li\n key={`first-widget-component:${i}`}\n ref={i === 0 ? elementRefs.firstElement : null}\n className={`${styles.itemSpacing} ${props.childClassName || ''}`}\n >\n <Component />\n </li>\n );\n }),\n ...items\n ];\n }\n\n if (lastChildren.length) {\n items = [\n ...items,\n ...lastChildren.map((child, i) => {\n const Component = child.component;\n\n return (\n <li\n key={`end-widget-component:${i}`}\n ref={i === lastChildren.length - 1 ? elementRefs.lastElement : null}\n className={`${styles.itemSpacing} ${props.childClassName || ''}`}\n >\n <Component />\n </li>\n );\n })\n ];\n }\n\n return <>{items}</>;\n }\n const widgetItems = React.useMemo(getWidgetItems, [\n widgetData, dynamicAttributes, state.offset, mediaQuery, ...props.widgetDataDeps || []\n ]);\n\n if (widgetData && !widgetData.length && !staticChildren?.length)\n return <></>;\n\n if (!widgetData || ObjectHelper.isEmpty(widgetData)) {\n return (\n <div ref={ref}>\n <PartialDynamicWidget\n partialLoadingComponent={props.partialLoadingComponent}\n partialLoadingOptions={props.partialLoadingOptions}\n />\n </div>\n );\n }\n\n const getSliderAnalyticsData = (type: WidgetInteraction) => ({\n ...props.analyticsData,\n id: props.id,\n name: props.heading,\n direction: type === WidgetInteraction.Next ? 'right' : 'left'\n });\n\n const hideButtons = isTouchScreen || props.hideButtons;\n\n return (\n <div className={`${props.noNegativePadding ? '' : 'mx-n4'}`}>\n <div className={`px-4 ${styles.header}`}>\n <WidgetHeader\n name={props.heading}\n description={props.description}\n appLink={props.headingAppLink}\n showSeeMoreLink={!!props.headingAppLink}\n />\n </div>\n\n <div className='position-relative'>\n <div className={`${props.noNegativePadding ? '' : 'px-4' } py-3 my-n3 position-relative ${isTouchScreen ? styles.mobileScroll : 'overflow-hidden-x'}`}>\n <div className={`position-relative ${props.hideButtons ? 'overflow-hidden-x' : ''}`}>\n {!hideButtons && (\n <WidgetButton\n direction={WidgetButtonDirection.Left}\n onClick={() => {\n focusPrev();\n\n dispatch({ type: WidgetInteraction.Previous });\n AnalyticsHelper.logUserAction(\n getSliderAnalyticsData(WidgetInteraction.Previous),\n WidgetHelper.getSliderAnalyticsOptions()\n );\n }}\n leftButtonClassName={`${styles.leftButton} ${props.noNegativePadding ? styles.leftButtonNoPadding : ''}`}\n leftGradientClassName={`${styles.leftGradient} ${props.noNegativePadding ? styles.leftGradientNoPadding : ''}`}\n hide={state.hideLeftButton}\n useGradientBackdrop\n />\n )}\n\n <SlidingListContainer\n position={state.offset}\n positionType={CssMeasurement.Pixels}\n onDrag={getDragHandler(elementRefs.container, state, dispatch, widgetSnapshot, setWidgetSnapshot)}\n onDragEnd={getDragEndHandler(elementRefs.container, setWidgetSnapshot)}\n ref={elementRefs.container}\n >\n {widgetItems}\n </SlidingListContainer>\n\n {!hideButtons && (\n <WidgetButton\n direction={WidgetButtonDirection.Right}\n onClick={() => {\n focusNext();\n\n dispatch({ type: WidgetInteraction.Next });\n AnalyticsHelper.logUserAction(\n getSliderAnalyticsData(WidgetInteraction.Next),\n WidgetHelper.getSliderAnalyticsOptions()\n );\n }}\n hide={state.hideRightButton}\n rightButtonClassName={`${styles.rightButton} ${props.noNegativePadding ? styles.rightButtonNoPadding : ''}`}\n rightGradientClassName={`${styles.rightGradient} ${props.noNegativePadding ? styles.rightGradientNoPadding : ''}`}\n useGradientBackdrop\n />\n )}\n </div>\n </div>\n </div>\n </div>\n );\n}\n\ntype PartialDynamicWidgetProps = Pick<DynamicWidgetProps, 'partialLoadingComponent'> & {\n partialLoadingOptions?: PartialLoadingOptions\n};\n\nexport const PartialDynamicWidget = (props: PartialDynamicWidgetProps) => {\n const { partialLoadingComponent: Component, partialLoadingOptions } = props;\n\n return (\n <div className='d-flex flex-nowrap overflow-hidden'>\n {PartialLoadingHelper.getPartialLoadingItems(partialLoadingOptions).map((item, idx) => <Component key={idx} />)}\n </div>\n );\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { FilterOption } from 'libs/shared/apps/search/interfaces';\nimport { TagItem } from 'libs/shared/components/tags/TagItem';\nimport { BaseObject, Tag } from 'libs/shared/interfaces';\n\nexport interface TagWidgetItemProps {\n appLink: Core.AppLink;\n data: Tag;\n selectedItems?: BaseObject[];\n onClick?: (data: Tag | FilterOption) => void;\n}\n\nexport function TagWidgetItem(props: TagWidgetItemProps): JSX.Element {\n const isSelected = props.selectedItems.find(selection => selection.id === props.data.id);\n\n const colorClass = isSelected ? `bg-gray-900 text-white` : 'bg-light';\n\n return (\n <TagItem\n tag={props.data}\n appLink={props.appLink}\n tagClass={`no-decoration ${colorClass} lh-1`}\n onClick={() => props.onClick(props.data)}\n />\n );\n}\n",":local {\n .tagItem {\n // Default tag styles\n line-height: 1rem;\n }\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { FilterOption, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterState } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { PartialTagItem } from 'libs/shared/components/tags/PartialTagItem';\nimport { DynamicWidget } from 'libs/shared/components/widgets/dynamic-widget/DynamicWidget';\nimport { TagWidgetItem, TagWidgetItemProps } from 'libs/shared/components/widgets/items/tag-widget-item/TagWidgetItem';\n\nimport styles from './tag-filter.module.scss';\n\ninterface TagFilterProps {\n filter: SearchFilter;\n queryParams: HashObject;\n isFetching?: boolean;\n}\n\nexport function TagFilter(props: TagFilterProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n\n if (!props.filter?.id)\n return <></>;\n\n const currentFilterState = state[props.filter.id];\n\n const { selection: selections } = currentFilterState;\n\n const unappliedOptions = props.filter?.options?.filter(opt => {\n return !selections?.find(selection => selection.id === opt.id);\n }) ?? [];\n\n function onClickOption(option: FilterOption): void {\n let nextFilterState: FilterState = null;\n\n let indexOfItem: number = -1;\n\n // Find the index of the selected item if it's already selected\n selections.find((selection, i) => {\n if (indexOfItem > -1)\n return;\n\n if (selection.id.toString() !== option.id.toString())\n return;\n\n indexOfItem = i;\n });\n\n if (indexOfItem >= 0) {\n const newItems = [ ...selections.slice(0, indexOfItem), ...selections.slice(indexOfItem + 1) ];\n \n nextFilterState = {\n active: !!newItems.length,\n selection: newItems\n };\n } else {\n nextFilterState = {\n active: true,\n selection: selections.concat(option)\n };\n }\n\n FilterHelper.applyFilter(\n [props.filter],\n currentFilterState,\n { [props.filter.id]: nextFilterState },\n state.appLink\n );\n }\n\n function getContainerClass(): string {\n let className = 'mb-3';\n\n if (collection.length && props.isFetching)\n className += ' mt-n1';\n else if (!collection.length && !props.isFetching)\n className += ' d-none';\n\n return className;\n }\n\n const collection = [ ...selections, ...(props.isFetching ? [] : unappliedOptions) ];\n\n return (\n <div className={(props.isFetching || collection.length) ? 'py-2' : ''}>\n <div className={getContainerClass()}>\n {(!!collection.length || props.isFetching) && (\n <DynamicWidget\n collection={collection}\n childComponent={(props: TagWidgetItemProps) => (\n <TagWidgetItem\n {...props}\n selectedItems={selections}\n onClick={onClickOption}\n />\n )}\n staticChildren={props.isFetching ?\n new Array(3).fill({\n component: () => <PartialTagItem tagClass={styles.tagItem} />,\n position: 'end'\n }) :\n []\n }\n partialLoadingComponent={() => (\n <div className='me-2'>\n <PartialTagItem tagClass={`${styles.tagItem}`} />\n </div>\n )}\n />\n )}\n </div>\n </div>\n );\n}\n","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { MoreFilters, SearchFilter } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext } from 'libs/shared/apps/search/reducers';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { PropsWithAnalyticsOptions } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport { SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM } from '../../utils/SharedSearchHelper';\n\ntype ResetButtonProps = PropsWithAnalyticsOptions<{\n currentQueryParam: string,\n mainFilters: Array<SearchFilter>,\n moreFilters: MoreFilters,\n alignLeft?: boolean\n}>;\n\nexport function ResetButton(props: ResetButtonProps): JSX.Element {\n const { state } = React.useContext(FilterContext);\n\n const onClickReset = () => {\n const currentParams = (ContextService.getCurrentRoute().appLink?.params ?? {}) as HashObject;\n const savedParams = ObjectHelper.pick(currentParams, [ 'query', SEARCH_CURRICULUM_CODE_PARAM, SEARCH_IN_PARAM ]);\n\n Core.AppLinkHelper.trigger({\n ...state.appLink,\n params: savedParams\n });\n };\n\n return (\n <DivButton\n onClick={onClickReset}\n className={`${props.alignLeft ? 'order-first' : ''} hover-text-underline cursor-pointer d-flex align-items-center mx-2`}\n >\n <Text namespace='search.resetButton' phrase='reset' />\n </DivButton>\n );\n}\n",":local {\n .partialFilterHeading {\n height: 1.5rem;\n width: 3.5rem;\n }\n\n .partialButton {\n height: 2.2rem;\n width: 5rem;\n }\n\n .filtersContainer {\n row-gap: map-get($spacers, 1);\n }\n}","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { HashObject } from 'libs/common/react/interfaces/HashObject';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AnalyticsOptions } from 'libs/analytics/interfaces';\n\nimport { FilterButton } from 'libs/shared/apps/search/components/filter-button/FilterButton';\nimport { MoreFiltersButton } from 'libs/shared/apps/search/components/filter-button/MoreFiltersButton';\nimport { TagFilter } from 'libs/shared/apps/search/components/filter-types/tag-filter/TagFilter';\nimport { ResetButton } from 'libs/shared/apps/search/components/reset-button/ResetButton';\nimport { MoreFilters, SearchFilter, SearchIndices } from 'libs/shared/apps/search/interfaces';\nimport { FilterContext, FilterReducer } from 'libs/shared/apps/search/reducers';\nimport { FilterHelper } from 'libs/shared/apps/search/utils/FilterHelper';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nimport styles from './search-filters.module.scss';\n\ntype SearchFiltersProps = {\n queryParams: HashObject,\n mainFilters: SearchFilter[],\n appLink: Core.AppLink,\n moreFilters?: MoreFilters,\n isFetchingOptions?: boolean,\n constantIndices?: SearchIndices[],\n analyticsOptions?: AnalyticsOptions,\n\n hideHeading?: boolean,\n hideDivider?: boolean,\n hideResetButton?: boolean,\n alignResetButtonLeft?: boolean,\n hideCaret?: boolean,\n\n /**\n * Incremental changes flag for new search\n */\n _hasNewSearch?: boolean,\n /**\n * Incremental changes flag for partner profiles\n */\n _hasPartnerProfiles?: boolean\n};\n\nexport function SearchFilters(props: SearchFiltersProps): JSX.Element {\n const { queryParams, appLink, hideHeading, isFetchingOptions, constantIndices = []} = props;\n\n const newState = React.useMemo(() => {\n return FilterHelper.deriveInitialStateFromQuery(queryParams, props.mainFilters, props.moreFilters, appLink);\n }, [ queryParams, isFetchingOptions ]);\n\n const [ state, dispatch ] = React.useReducer(FilterReducer, newState);\n\n React.useEffect(() => {\n if (ObjectHelper.isEqual(newState, state))\n return;\n\n dispatch({\n type: 'update',\n payload: newState\n });\n\n if (props.analyticsOptions) {\n FilterHelper.logFilterEvent(\n props.mainFilters,\n props.moreFilters,\n newState,\n queryParams.query,\n props.analyticsOptions\n );\n }\n }, [newState]);\n\n const indices = ArrayHelper.uniq([\n ...FilterHelper.getAppliedIndices(queryParams, props._hasNewSearch, props._hasPartnerProfiles),\n ...constantIndices\n ]);\n\n const { mainFilters, moreFilters } = FilterHelper.mixinDisabledFields(\n state,\n indices,\n props.mainFilters,\n props.moreFilters\n );\n\n // Separate the tag filter as it's rendered differently\n const mainFiltersWithoutTags = mainFilters.filter(f => f.type !== 'tag');\n const tagFilter = mainFilters.find(f => f.type === 'tag');\n\n return (\n <FilterContext.Provider value={{ state, dispatch }}>\n <LanguageNamespaceContext.Provider value='search.searchFilters'>\n <section>\n <div className={classNames(\n 'd-flex',\n !props.hideDivider && 'border-bottom pb-3 mb-3',\n (props._hasNewSearch && props.hideDivider && 'pb-3'),\n (props._hasNewSearch && !props.hideDivider && 'border-gray-300')\n )}>\n {!hideHeading && (\n <h2 className='h5 mb-0 d-inline-block pe-2 border-end d-flex align-items-center'>\n <Text phrase='heading' />\n </h2>\n )}\n\n <div className={classNames(`d-flex flex-wrap ${styles.filtersContainer}`, !hideHeading && 'ms-2')}>\n {mainFiltersWithoutTags.map(f => (\n <FilterButton key={f.id} filter={f} hideCaret={props.hideCaret} />\n ))}\n\n {moreFilters && <MoreFiltersButton filter={moreFilters} />}\n\n {FilterHelper.hasActiveFilters(queryParams) && !props.hideResetButton && (\n <ResetButton\n mainFilters={props.mainFilters}\n moreFilters={props.moreFilters}\n currentQueryParam={queryParams.query}\n analyticsOptions={props.analyticsOptions}\n alignLeft={props.alignResetButtonLeft}\n />\n )}\n </div>\n </div>\n \n <TagFilter\n filter={tagFilter}\n queryParams={queryParams}\n isFetching={props.isFetchingOptions}\n />\n </section>\n </LanguageNamespaceContext.Provider>\n </FilterContext.Provider>\n );\n}\n"],"mappings":"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"}