@clickview/curator 1.100.0-rc.1 → 1.100.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 (321) hide show
  1. package/dist/.vite/manifest.json +1779 -1779
  2. package/dist/Assets/js/dist/scripts/{CYhNyVj0.chunk.js → -6zuD8lo.chunk.js} +2 -2
  3. package/dist/Assets/js/dist/scripts/{CYhNyVj0.chunk.js.map → -6zuD8lo.chunk.js.map} +1 -1
  4. package/dist/Assets/js/dist/scripts/{D28bEsam.chunk.js → 0A42jU2r.chunk.js} +2 -2
  5. package/dist/Assets/js/dist/scripts/{D28bEsam.chunk.js.map → 0A42jU2r.chunk.js.map} +1 -1
  6. package/dist/Assets/js/dist/scripts/{oYHUjbwb2.chunk.js → 0ogjGD4J2.chunk.js} +2 -2
  7. package/dist/Assets/js/dist/scripts/{oYHUjbwb2.chunk.js.map → 0ogjGD4J2.chunk.js.map} +1 -1
  8. package/dist/Assets/js/dist/scripts/{PeuFojmJ2.chunk.js → 2aCj1HHJ2.chunk.js} +2 -2
  9. package/dist/Assets/js/dist/scripts/{PeuFojmJ2.chunk.js.map → 2aCj1HHJ2.chunk.js.map} +1 -1
  10. package/dist/Assets/js/dist/scripts/{q7pjZoNd.chunk.js → 2zbtFQka.chunk.js} +2 -2
  11. package/dist/Assets/js/dist/scripts/{q7pjZoNd.chunk.js.map → 2zbtFQka.chunk.js.map} +1 -1
  12. package/dist/Assets/js/dist/scripts/{0S5J0xX22.chunk.js → 3IQ_8AZP2.chunk.js} +2 -2
  13. package/dist/Assets/js/dist/scripts/{0S5J0xX22.chunk.js.map → 3IQ_8AZP2.chunk.js.map} +1 -1
  14. package/dist/Assets/js/dist/scripts/{DvP7S5Uq.chunk.js → 3eMwLZ5D.chunk.js} +2 -2
  15. package/dist/Assets/js/dist/scripts/{DvP7S5Uq.chunk.js.map → 3eMwLZ5D.chunk.js.map} +1 -1
  16. package/dist/Assets/js/dist/scripts/{y1L3G7XA2.chunk.js → 4Tx2JSvk2.chunk.js} +2 -2
  17. package/dist/Assets/js/dist/scripts/{y1L3G7XA2.chunk.js.map → 4Tx2JSvk2.chunk.js.map} +1 -1
  18. package/dist/Assets/js/dist/scripts/{BbR7yW4A2.chunk.js → 5uVJfyDx2.chunk.js} +2 -2
  19. package/dist/Assets/js/dist/scripts/{BbR7yW4A2.chunk.js.map → 5uVJfyDx2.chunk.js.map} +1 -1
  20. package/dist/Assets/js/dist/scripts/{B52yjTo5.chunk.js → 6l2s6d3Q.chunk.js} +2 -2
  21. package/dist/Assets/js/dist/scripts/{B52yjTo5.chunk.js.map → 6l2s6d3Q.chunk.js.map} +1 -1
  22. package/dist/Assets/js/dist/scripts/{DezIbRcB2.chunk.js → 8RAh0VA72.chunk.js} +2 -2
  23. package/dist/Assets/js/dist/scripts/{DezIbRcB2.chunk.js.map → 8RAh0VA72.chunk.js.map} +1 -1
  24. package/dist/Assets/js/dist/scripts/{CixcMUHF.chunk.js → 9nk_zFtT.chunk.js} +2 -2
  25. package/dist/Assets/js/dist/scripts/{CixcMUHF.chunk.js.map → 9nk_zFtT.chunk.js.map} +1 -1
  26. package/dist/Assets/js/dist/scripts/{Bk9vy70e2.chunk.js → Ae4rMqFm2.chunk.js} +2 -2
  27. package/dist/Assets/js/dist/scripts/{Bk9vy70e2.chunk.js.map → Ae4rMqFm2.chunk.js.map} +1 -1
  28. package/dist/Assets/js/dist/scripts/{Bzh_AwaG.chunk.js → B0mCquXn.chunk.js} +2 -2
  29. package/dist/Assets/js/dist/scripts/{Bzh_AwaG.chunk.js.map → B0mCquXn.chunk.js.map} +1 -1
  30. package/dist/Assets/js/dist/scripts/B1pBJzjh.chunk.js +1 -0
  31. package/dist/Assets/js/dist/scripts/{BswFY0mR2.chunk.js → B6IinlWw2.chunk.js} +2 -2
  32. package/dist/Assets/js/dist/scripts/{BswFY0mR2.chunk.js.map → B6IinlWw2.chunk.js.map} +1 -1
  33. package/dist/Assets/js/dist/scripts/{ClpIRgLR.chunk.js → B6NMAAhW.chunk.js} +2 -2
  34. package/dist/Assets/js/dist/scripts/{ClpIRgLR.chunk.js.map → B6NMAAhW.chunk.js.map} +1 -1
  35. package/dist/Assets/js/dist/scripts/{BCMXlwdC2.chunk.js → B8RZKQTs2.chunk.js} +2 -2
  36. package/dist/Assets/js/dist/scripts/{BCMXlwdC2.chunk.js.map → B8RZKQTs2.chunk.js.map} +1 -1
  37. package/dist/Assets/js/dist/scripts/{CymdouaN.chunk.js → B9R92bqj.chunk.js} +2 -2
  38. package/dist/Assets/js/dist/scripts/{CymdouaN.chunk.js.map → B9R92bqj.chunk.js.map} +1 -1
  39. package/dist/Assets/js/dist/scripts/{CtVYDK7g.chunk.js → BAFYJZ4c.chunk.js} +2 -2
  40. package/dist/Assets/js/dist/scripts/{CtVYDK7g.chunk.js.map → BAFYJZ4c.chunk.js.map} +1 -1
  41. package/dist/Assets/js/dist/scripts/{_wZpe632.chunk.js → BFPSIGJg.chunk.js} +2 -2
  42. package/dist/Assets/js/dist/scripts/{_wZpe632.chunk.js.map → BFPSIGJg.chunk.js.map} +1 -1
  43. package/dist/Assets/js/dist/scripts/{BNHULwJy2.chunk.js → BGiLDtc92.chunk.js} +2 -2
  44. package/dist/Assets/js/dist/scripts/{BNHULwJy2.chunk.js.map → BGiLDtc92.chunk.js.map} +1 -1
  45. package/dist/Assets/js/dist/scripts/{DA9R8atp2.chunk.js → BH6LIpwu2.chunk.js} +2 -2
  46. package/dist/Assets/js/dist/scripts/{DA9R8atp2.chunk.js.map → BH6LIpwu2.chunk.js.map} +1 -1
  47. package/dist/Assets/js/dist/scripts/{DbrVjVdn.chunk.js → BMj3pXcm.chunk.js} +2 -2
  48. package/dist/Assets/js/dist/scripts/{DbrVjVdn.chunk.js.map → BMj3pXcm.chunk.js.map} +1 -1
  49. package/dist/Assets/js/dist/scripts/{CDvLjxwS.chunk.js → BQTfNBFU.chunk.js} +2 -2
  50. package/dist/Assets/js/dist/scripts/{CDvLjxwS.chunk.js.map → BQTfNBFU.chunk.js.map} +1 -1
  51. package/dist/Assets/js/dist/scripts/{mStmtFRo.chunk.js → BT-jeT7C.chunk.js} +2 -2
  52. package/dist/Assets/js/dist/scripts/{mStmtFRo.chunk.js.map → BT-jeT7C.chunk.js.map} +1 -1
  53. package/dist/Assets/js/dist/scripts/{FlF2O19P2.chunk.js → BUD4osIg2.chunk.js} +2 -2
  54. package/dist/Assets/js/dist/scripts/{FlF2O19P2.chunk.js.map → BUD4osIg2.chunk.js.map} +1 -1
  55. package/dist/Assets/js/dist/scripts/{DWS9yr24.chunk.js → BVoG71Kc.chunk.js} +2 -2
  56. package/dist/Assets/js/dist/scripts/{DWS9yr24.chunk.js.map → BVoG71Kc.chunk.js.map} +1 -1
  57. package/dist/Assets/js/dist/scripts/{B9tf3oT62.chunk.js → BW5iVK1B2.chunk.js} +2 -2
  58. package/dist/Assets/js/dist/scripts/{B9tf3oT62.chunk.js.map → BW5iVK1B2.chunk.js.map} +1 -1
  59. package/dist/Assets/js/dist/scripts/{C2mEE4FT.chunk.js → BW9r-3iO.chunk.js} +2 -2
  60. package/dist/Assets/js/dist/scripts/{C2mEE4FT.chunk.js.map → BW9r-3iO.chunk.js.map} +1 -1
  61. package/dist/Assets/js/dist/scripts/{Dpgqkqbp.chunk.js → BX1tMzoa.chunk.js} +2 -2
  62. package/dist/Assets/js/dist/scripts/{Dpgqkqbp.chunk.js.map → BX1tMzoa.chunk.js.map} +1 -1
  63. package/dist/Assets/js/dist/scripts/{DVRzbAn6.chunk.js → BXaC-l33.chunk.js} +2 -2
  64. package/dist/Assets/js/dist/scripts/{DVRzbAn6.chunk.js.map → BXaC-l33.chunk.js.map} +1 -1
  65. package/dist/Assets/js/dist/scripts/{BaR7D4NT2.chunk.js → BY-c3M2b2.chunk.js} +2 -2
  66. package/dist/Assets/js/dist/scripts/{BaR7D4NT2.chunk.js.map → BY-c3M2b2.chunk.js.map} +1 -1
  67. package/dist/Assets/js/dist/scripts/{CJpVJtZk.chunk.js → BYMuPFbe.chunk.js} +2 -2
  68. package/dist/Assets/js/dist/scripts/{CJpVJtZk.chunk.js.map → BYMuPFbe.chunk.js.map} +1 -1
  69. package/dist/Assets/js/dist/scripts/{C5INFWaM2.chunk.js → BaOAOuSc2.chunk.js} +2 -2
  70. package/dist/Assets/js/dist/scripts/{C5INFWaM2.chunk.js.map → BaOAOuSc2.chunk.js.map} +1 -1
  71. package/dist/Assets/js/dist/scripts/{wAWlO6hc.chunk.js → Bb_f3Lku.chunk.js} +2 -2
  72. package/dist/Assets/js/dist/scripts/{wAWlO6hc.chunk.js.map → Bb_f3Lku.chunk.js.map} +1 -1
  73. package/dist/Assets/js/dist/scripts/{BLJO44vl.chunk.js → BdJYoUIO.chunk.js} +2 -2
  74. package/dist/Assets/js/dist/scripts/{BLJO44vl.chunk.js.map → BdJYoUIO.chunk.js.map} +1 -1
  75. package/dist/Assets/js/dist/scripts/{CW2k5Ut-2.chunk.js → Bf-6iyfX2.chunk.js} +2 -2
  76. package/dist/Assets/js/dist/scripts/{CW2k5Ut-2.chunk.js.map → Bf-6iyfX2.chunk.js.map} +1 -1
  77. package/dist/Assets/js/dist/scripts/{DxL0ZEcN2.chunk.js → BiPUuGEE2.chunk.js} +2 -2
  78. package/dist/Assets/js/dist/scripts/{DxL0ZEcN2.chunk.js.map → BiPUuGEE2.chunk.js.map} +1 -1
  79. package/dist/Assets/js/dist/scripts/{2XS-c0Xo.chunk.js → Bj4-NRWf.chunk.js} +2 -2
  80. package/dist/Assets/js/dist/scripts/{2XS-c0Xo.chunk.js.map → Bj4-NRWf.chunk.js.map} +1 -1
  81. package/dist/Assets/js/dist/scripts/{D13ViJt82.chunk.js → BkVcraos2.chunk.js} +2 -2
  82. package/dist/Assets/js/dist/scripts/{D13ViJt82.chunk.js.map → BkVcraos2.chunk.js.map} +1 -1
  83. package/dist/Assets/js/dist/scripts/{U1L4Dfoc.chunk.js → BkZ7WS_H.chunk.js} +2 -2
  84. package/dist/Assets/js/dist/scripts/{U1L4Dfoc.chunk.js.map → BkZ7WS_H.chunk.js.map} +1 -1
  85. package/dist/Assets/js/dist/scripts/{DoQiTqRX2.chunk.js → BoMt5mMW2.chunk.js} +2 -2
  86. package/dist/Assets/js/dist/scripts/{DoQiTqRX2.chunk.js.map → BoMt5mMW2.chunk.js.map} +1 -1
  87. package/dist/Assets/js/dist/scripts/{Da_9BBKD2.chunk.js → Bo_WsHZq2.chunk.js} +2 -2
  88. package/dist/Assets/js/dist/scripts/{Da_9BBKD2.chunk.js.map → Bo_WsHZq2.chunk.js.map} +1 -1
  89. package/dist/Assets/js/dist/scripts/{CnyrKBG0.chunk.js → BpV5ErII.chunk.js} +2 -2
  90. package/dist/Assets/js/dist/scripts/{CnyrKBG0.chunk.js.map → BpV5ErII.chunk.js.map} +1 -1
  91. package/dist/Assets/js/dist/scripts/{Dfhl7nI62.chunk.js → BrBPGjLi2.chunk.js} +2 -2
  92. package/dist/Assets/js/dist/scripts/{Dfhl7nI62.chunk.js.map → BrBPGjLi2.chunk.js.map} +1 -1
  93. package/dist/Assets/js/dist/scripts/{DcxGcCkR.chunk.js → BrHyZG_m.chunk.js} +2 -2
  94. package/dist/Assets/js/dist/scripts/{DcxGcCkR.chunk.js.map → BrHyZG_m.chunk.js.map} +1 -1
  95. package/dist/Assets/js/dist/scripts/{FXPxauLF.chunk.js → Bu4F3uuX.chunk.js} +2 -2
  96. package/dist/Assets/js/dist/scripts/{FXPxauLF.chunk.js.map → Bu4F3uuX.chunk.js.map} +1 -1
  97. package/dist/Assets/js/dist/scripts/{DZdJx-7j.chunk.js → BvW9SXzy.chunk.js} +2 -2
  98. package/dist/Assets/js/dist/scripts/{DZdJx-7j.chunk.js.map → BvW9SXzy.chunk.js.map} +1 -1
  99. package/dist/Assets/js/dist/scripts/{CAU0Lbgd.chunk.js → BwKHls91.chunk.js} +2 -2
  100. package/dist/Assets/js/dist/scripts/{CAU0Lbgd.chunk.js.map → BwKHls91.chunk.js.map} +1 -1
  101. package/dist/Assets/js/dist/scripts/{BiTzUyxj2.chunk.js → BxZNJjbX2.chunk.js} +2 -2
  102. package/dist/Assets/js/dist/scripts/{BiTzUyxj2.chunk.js.map → BxZNJjbX2.chunk.js.map} +1 -1
  103. package/dist/Assets/js/dist/scripts/{cymXuIcM.chunk.js → BygVW5WL.chunk.js} +2 -2
  104. package/dist/Assets/js/dist/scripts/{cymXuIcM.chunk.js.map → BygVW5WL.chunk.js.map} +1 -1
  105. package/dist/Assets/js/dist/scripts/{Dx07A6Ct.chunk.js → ByzsHBuo.chunk.js} +2 -2
  106. package/dist/Assets/js/dist/scripts/{Dx07A6Ct.chunk.js.map → ByzsHBuo.chunk.js.map} +1 -1
  107. package/dist/Assets/js/dist/scripts/C-M2om56.chunk.js +3 -0
  108. package/dist/Assets/js/dist/scripts/C-M2om56.chunk.js.map +1 -0
  109. package/dist/Assets/js/dist/scripts/{B6dlmRQL.chunk.js → C0UYMHUe.chunk.js} +2 -2
  110. package/dist/Assets/js/dist/scripts/{B6dlmRQL.chunk.js.map → C0UYMHUe.chunk.js.map} +1 -1
  111. package/dist/Assets/js/dist/scripts/{V0N7tCBl.chunk.js → C0_pEFCD.chunk.js} +2 -2
  112. package/dist/Assets/js/dist/scripts/{V0N7tCBl.chunk.js.map → C0_pEFCD.chunk.js.map} +1 -1
  113. package/dist/Assets/js/dist/scripts/{Cpr1J8Rk2.chunk.js → C2jRLu4_2.chunk.js} +2 -2
  114. package/dist/Assets/js/dist/scripts/{Cpr1J8Rk2.chunk.js.map → C2jRLu4_2.chunk.js.map} +1 -1
  115. package/dist/Assets/js/dist/scripts/{CY56FWb9.chunk.js → C2tBl3l9.chunk.js} +2 -2
  116. package/dist/Assets/js/dist/scripts/{CY56FWb9.chunk.js.map → C2tBl3l9.chunk.js.map} +1 -1
  117. package/dist/Assets/js/dist/scripts/{C3Lx9PwR.chunk.js → C4eazpDh.chunk.js} +2 -2
  118. package/dist/Assets/js/dist/scripts/{C3Lx9PwR.chunk.js.map → C4eazpDh.chunk.js.map} +1 -1
  119. package/dist/Assets/js/dist/scripts/{puobgAYi.chunk.js → CBq4vrjT.chunk.js} +2 -2
  120. package/dist/Assets/js/dist/scripts/{puobgAYi.chunk.js.map → CBq4vrjT.chunk.js.map} +1 -1
  121. package/dist/Assets/js/dist/scripts/{Bcx1C8ae.chunk.js → CBzqRw-k.chunk.js} +2 -2
  122. package/dist/Assets/js/dist/scripts/{Bcx1C8ae.chunk.js.map → CBzqRw-k.chunk.js.map} +1 -1
  123. package/dist/Assets/js/dist/scripts/{BD6DIPGL2.chunk.js → CDAdfAL02.chunk.js} +2 -2
  124. package/dist/Assets/js/dist/scripts/{BD6DIPGL2.chunk.js.map → CDAdfAL02.chunk.js.map} +1 -1
  125. package/dist/Assets/js/dist/scripts/{Ddp1uNfH.chunk.js → CE1Dxq8p.chunk.js} +2 -2
  126. package/dist/Assets/js/dist/scripts/{Ddp1uNfH.chunk.js.map → CE1Dxq8p.chunk.js.map} +1 -1
  127. package/dist/Assets/js/dist/scripts/{C99MPG7E.chunk.js → CG2julEA.chunk.js} +2 -2
  128. package/dist/Assets/js/dist/scripts/{C99MPG7E.chunk.js.map → CG2julEA.chunk.js.map} +1 -1
  129. package/dist/Assets/js/dist/scripts/{tyY3GHEC2.chunk.js → CGcN4g0d2.chunk.js} +2 -2
  130. package/dist/Assets/js/dist/scripts/{tyY3GHEC2.chunk.js.map → CGcN4g0d2.chunk.js.map} +1 -1
  131. package/dist/Assets/js/dist/scripts/{wODD7tmB2.chunk.js → CJmV_FfR2.chunk.js} +2 -2
  132. package/dist/Assets/js/dist/scripts/{wODD7tmB2.chunk.js.map → CJmV_FfR2.chunk.js.map} +1 -1
  133. package/dist/Assets/js/dist/scripts/{DavA1dZZ.chunk.js → CKvVGIRL.chunk.js} +2 -2
  134. package/dist/Assets/js/dist/scripts/{DavA1dZZ.chunk.js.map → CKvVGIRL.chunk.js.map} +1 -1
  135. package/dist/Assets/js/dist/scripts/{CrndJnZp.chunk.js → CL1DcbTZ.chunk.js} +2 -2
  136. package/dist/Assets/js/dist/scripts/{CrndJnZp.chunk.js.map → CL1DcbTZ.chunk.js.map} +1 -1
  137. package/dist/Assets/js/dist/scripts/{DLLL2lwS.chunk.js → CNLx6_fS.chunk.js} +2 -2
  138. package/dist/Assets/js/dist/scripts/{DLLL2lwS.chunk.js.map → CNLx6_fS.chunk.js.map} +1 -1
  139. package/dist/Assets/js/dist/scripts/{w2lackHw.chunk.js → CNUVs80P.chunk.js} +2 -2
  140. package/dist/Assets/js/dist/scripts/{w2lackHw.chunk.js.map → CNUVs80P.chunk.js.map} +1 -1
  141. package/dist/Assets/js/dist/scripts/{CCzvD0H4.chunk.js → CPa__SNX.chunk.js} +2 -2
  142. package/dist/Assets/js/dist/scripts/{CCzvD0H4.chunk.js.map → CPa__SNX.chunk.js.map} +1 -1
  143. package/dist/Assets/js/dist/scripts/{DeDh-wVP.chunk.js → CSA2Tnv9.chunk.js} +2 -2
  144. package/dist/Assets/js/dist/scripts/{DeDh-wVP.chunk.js.map → CSA2Tnv9.chunk.js.map} +1 -1
  145. package/dist/Assets/js/dist/scripts/{CjZJx6-O2.chunk.js → CT-xEpNT2.chunk.js} +2 -2
  146. package/dist/Assets/js/dist/scripts/{CjZJx6-O2.chunk.js.map → CT-xEpNT2.chunk.js.map} +1 -1
  147. package/dist/Assets/js/dist/scripts/{BRPP3VZ1.chunk.js → CT0vfLa0.chunk.js} +2 -2
  148. package/dist/Assets/js/dist/scripts/{BRPP3VZ1.chunk.js.map → CT0vfLa0.chunk.js.map} +1 -1
  149. package/dist/Assets/js/dist/scripts/{DGjNB2Bz.chunk.js → CUDnXypB.chunk.js} +2 -2
  150. package/dist/Assets/js/dist/scripts/{DGjNB2Bz.chunk.js.map → CUDnXypB.chunk.js.map} +1 -1
  151. package/dist/Assets/js/dist/scripts/{cXanUGwK.chunk.js → CeMQZB5J.chunk.js} +2 -2
  152. package/dist/Assets/js/dist/scripts/{cXanUGwK.chunk.js.map → CeMQZB5J.chunk.js.map} +1 -1
  153. package/dist/Assets/js/dist/scripts/Cf5cjLzK.chunk.js +2 -0
  154. package/dist/Assets/js/dist/scripts/{D2iK_uRt.chunk.js.map → Cf5cjLzK.chunk.js.map} +1 -1
  155. package/dist/Assets/js/dist/scripts/{CRNBuqmR.chunk.js → CfGaxIgd.chunk.js} +2 -2
  156. package/dist/Assets/js/dist/scripts/{CRNBuqmR.chunk.js.map → CfGaxIgd.chunk.js.map} +1 -1
  157. package/dist/Assets/js/dist/scripts/{BNr7ZL3F2.chunk.js → Cqfub35W2.chunk.js} +2 -2
  158. package/dist/Assets/js/dist/scripts/{BNr7ZL3F2.chunk.js.map → Cqfub35W2.chunk.js.map} +1 -1
  159. package/dist/Assets/js/dist/scripts/{DRmwJ1it2.chunk.js → Cv8UpP5_2.chunk.js} +2 -2
  160. package/dist/Assets/js/dist/scripts/{DRmwJ1it2.chunk.js.map → Cv8UpP5_2.chunk.js.map} +1 -1
  161. package/dist/Assets/js/dist/scripts/{DOfeXfSj.chunk.js → CvV6jx2d.chunk.js} +2 -2
  162. package/dist/Assets/js/dist/scripts/{DOfeXfSj.chunk.js.map → CvV6jx2d.chunk.js.map} +1 -1
  163. package/dist/Assets/js/dist/scripts/{DnGnhqys.chunk.js → CxENQntH.chunk.js} +2 -2
  164. package/dist/Assets/js/dist/scripts/{DnGnhqys.chunk.js.map → CxENQntH.chunk.js.map} +1 -1
  165. package/dist/Assets/js/dist/scripts/{NMDkdR-8.chunk.js → CxIfJCSc.chunk.js} +2 -2
  166. package/dist/Assets/js/dist/scripts/{NMDkdR-8.chunk.js.map → CxIfJCSc.chunk.js.map} +1 -1
  167. package/dist/Assets/js/dist/scripts/{B9H-d-YC.chunk.js → CxggKQxV.chunk.js} +2 -2
  168. package/dist/Assets/js/dist/scripts/{B9H-d-YC.chunk.js.map → CxggKQxV.chunk.js.map} +1 -1
  169. package/dist/Assets/js/dist/scripts/{B3I44IzQ.chunk.js → CyNNZ1So.chunk.js} +2 -2
  170. package/dist/Assets/js/dist/scripts/{B3I44IzQ.chunk.js.map → CyNNZ1So.chunk.js.map} +1 -1
  171. package/dist/Assets/js/dist/scripts/{B2V1N14S.chunk.js → Cz-WSyAE.chunk.js} +2 -2
  172. package/dist/Assets/js/dist/scripts/{B2V1N14S.chunk.js.map → Cz-WSyAE.chunk.js.map} +1 -1
  173. package/dist/Assets/js/dist/scripts/{S9cTzcQc2.chunk.js → D2aQFJWt2.chunk.js} +2 -2
  174. package/dist/Assets/js/dist/scripts/{S9cTzcQc2.chunk.js.map → D2aQFJWt2.chunk.js.map} +1 -1
  175. package/dist/Assets/js/dist/scripts/{CEsXUxxo2.chunk.js → D2h9W4GA2.chunk.js} +2 -2
  176. package/dist/Assets/js/dist/scripts/{CEsXUxxo2.chunk.js.map → D2h9W4GA2.chunk.js.map} +1 -1
  177. package/dist/Assets/js/dist/scripts/{DqCsVhOS.chunk.js → D3NAhMJm.chunk.js} +2 -2
  178. package/dist/Assets/js/dist/scripts/{DqCsVhOS.chunk.js.map → D3NAhMJm.chunk.js.map} +1 -1
  179. package/dist/Assets/js/dist/scripts/{DpM1KgHy.chunk.js → D3aWaqBW.chunk.js} +2 -2
  180. package/dist/Assets/js/dist/scripts/{DpM1KgHy.chunk.js.map → D3aWaqBW.chunk.js.map} +1 -1
  181. package/dist/Assets/js/dist/scripts/{CxtxOtyF2.chunk.js → D4xcR0492.chunk.js} +2 -2
  182. package/dist/Assets/js/dist/scripts/{CxtxOtyF2.chunk.js.map → D4xcR0492.chunk.js.map} +1 -1
  183. package/dist/Assets/js/dist/scripts/{BEeh_Vbr.chunk.js → D5ek2PiI.chunk.js} +2 -2
  184. package/dist/Assets/js/dist/scripts/{BEeh_Vbr.chunk.js.map → D5ek2PiI.chunk.js.map} +1 -1
  185. package/dist/Assets/js/dist/scripts/{DjqQYm43.chunk.js → D61ei_h6.chunk.js} +2 -2
  186. package/dist/Assets/js/dist/scripts/{DjqQYm43.chunk.js.map → D61ei_h6.chunk.js.map} +1 -1
  187. package/dist/Assets/js/dist/scripts/{lgpeNdac.chunk.js → D6wyTufc.chunk.js} +2 -2
  188. package/dist/Assets/js/dist/scripts/{lgpeNdac.chunk.js.map → D6wyTufc.chunk.js.map} +1 -1
  189. package/dist/Assets/js/dist/scripts/{B8li8ced.chunk.js → D7I90XOo.chunk.js} +2 -2
  190. package/dist/Assets/js/dist/scripts/{B8li8ced.chunk.js.map → D7I90XOo.chunk.js.map} +1 -1
  191. package/dist/Assets/js/dist/scripts/{DBAwgllB.chunk.js → DArfNv9S.chunk.js} +2 -2
  192. package/dist/Assets/js/dist/scripts/{DBAwgllB.chunk.js.map → DArfNv9S.chunk.js.map} +1 -1
  193. package/dist/Assets/js/dist/scripts/{B6uYrrzJ2.chunk.js → DB-51xws2.chunk.js} +2 -2
  194. package/dist/Assets/js/dist/scripts/{B6uYrrzJ2.chunk.js.map → DB-51xws2.chunk.js.map} +1 -1
  195. package/dist/Assets/js/dist/scripts/{C-flCrUr.chunk.js → DENdEA1F.chunk.js} +2 -2
  196. package/dist/Assets/js/dist/scripts/{C-flCrUr.chunk.js.map → DENdEA1F.chunk.js.map} +1 -1
  197. package/dist/Assets/js/dist/scripts/{BuF_pg9-2.chunk.js → DFYiLmms2.chunk.js} +2 -2
  198. package/dist/Assets/js/dist/scripts/{BuF_pg9-2.chunk.js.map → DFYiLmms2.chunk.js.map} +1 -1
  199. package/dist/Assets/js/dist/scripts/{BE6LUVEo2.chunk.js → DHa-x1js2.chunk.js} +2 -2
  200. package/dist/Assets/js/dist/scripts/{BE6LUVEo2.chunk.js.map → DHa-x1js2.chunk.js.map} +1 -1
  201. package/dist/Assets/js/dist/scripts/{DDHep0UM.chunk.js → DHeA2NJS.chunk.js} +2 -2
  202. package/dist/Assets/js/dist/scripts/{DDHep0UM.chunk.js.map → DHeA2NJS.chunk.js.map} +1 -1
  203. package/dist/Assets/js/dist/scripts/{D5OaPA-v.chunk.js → DIDxfMO_.chunk.js} +2 -2
  204. package/dist/Assets/js/dist/scripts/{D5OaPA-v.chunk.js.map → DIDxfMO_.chunk.js.map} +1 -1
  205. package/dist/Assets/js/dist/scripts/{CV7UIOmh2.chunk.js → DMq1wDNm2.chunk.js} +2 -2
  206. package/dist/Assets/js/dist/scripts/{CV7UIOmh2.chunk.js.map → DMq1wDNm2.chunk.js.map} +1 -1
  207. package/dist/Assets/js/dist/scripts/{ByMU9ltp2.chunk.js → DNWM9yfh2.chunk.js} +2 -2
  208. package/dist/Assets/js/dist/scripts/{ByMU9ltp2.chunk.js.map → DNWM9yfh2.chunk.js.map} +1 -1
  209. package/dist/Assets/js/dist/scripts/{DFwtjofq2.chunk.js → DSj7VCEo2.chunk.js} +2 -2
  210. package/dist/Assets/js/dist/scripts/{DFwtjofq2.chunk.js.map → DSj7VCEo2.chunk.js.map} +1 -1
  211. package/dist/Assets/js/dist/scripts/{BSYuzR8N2.chunk.js → DSvehN9D2.chunk.js} +2 -2
  212. package/dist/Assets/js/dist/scripts/{BSYuzR8N2.chunk.js.map → DSvehN9D2.chunk.js.map} +1 -1
  213. package/dist/Assets/js/dist/scripts/{FS74_jrx.chunk.js → DTvCgZ4c.chunk.js} +2 -2
  214. package/dist/Assets/js/dist/scripts/{FS74_jrx.chunk.js.map → DTvCgZ4c.chunk.js.map} +1 -1
  215. package/dist/Assets/js/dist/scripts/{C7Gmh7eY.chunk.js → DWHKdmdQ.chunk.js} +2 -2
  216. package/dist/Assets/js/dist/scripts/{C7Gmh7eY.chunk.js.map → DWHKdmdQ.chunk.js.map} +1 -1
  217. package/dist/Assets/js/dist/scripts/{DXcaOjI_.chunk.js → DYFGF9Pe.chunk.js} +2 -2
  218. package/dist/Assets/js/dist/scripts/{DXcaOjI_.chunk.js.map → DYFGF9Pe.chunk.js.map} +1 -1
  219. package/dist/Assets/js/dist/scripts/{CIw53qNO2.chunk.js → DYOxTenc2.chunk.js} +2 -2
  220. package/dist/Assets/js/dist/scripts/{CIw53qNO2.chunk.js.map → DYOxTenc2.chunk.js.map} +1 -1
  221. package/dist/Assets/js/dist/scripts/{CignflP_2.chunk.js → DZthp5T62.chunk.js} +2 -2
  222. package/dist/Assets/js/dist/scripts/{CignflP_2.chunk.js.map → DZthp5T62.chunk.js.map} +1 -1
  223. package/dist/Assets/js/dist/scripts/{BlqDwJRY.chunk.js → Djgwr16q.chunk.js} +2 -2
  224. package/dist/Assets/js/dist/scripts/{BlqDwJRY.chunk.js.map → Djgwr16q.chunk.js.map} +1 -1
  225. package/dist/Assets/js/dist/scripts/{BwToh2X9.chunk.js → DjnvbVQs.chunk.js} +2 -2
  226. package/dist/Assets/js/dist/scripts/{BwToh2X9.chunk.js.map → DjnvbVQs.chunk.js.map} +1 -1
  227. package/dist/Assets/js/dist/scripts/{UelJUmgx2.chunk.js → DmrhyI9D2.chunk.js} +2 -2
  228. package/dist/Assets/js/dist/scripts/{UelJUmgx2.chunk.js.map → DmrhyI9D2.chunk.js.map} +1 -1
  229. package/dist/Assets/js/dist/scripts/{0KUhq7W7.chunk.js → DnZGILQc.chunk.js} +2 -2
  230. package/dist/Assets/js/dist/scripts/{0KUhq7W7.chunk.js.map → DnZGILQc.chunk.js.map} +1 -1
  231. package/dist/Assets/js/dist/scripts/{BSPrErub.chunk.js → DqnZw1cj.chunk.js} +2 -2
  232. package/dist/Assets/js/dist/scripts/{BSPrErub.chunk.js.map → DqnZw1cj.chunk.js.map} +1 -1
  233. package/dist/Assets/js/dist/scripts/{Bkx2vKcX2.chunk.js → DrAKpy8L2.chunk.js} +2 -2
  234. package/dist/Assets/js/dist/scripts/{Bkx2vKcX2.chunk.js.map → DrAKpy8L2.chunk.js.map} +1 -1
  235. package/dist/Assets/js/dist/scripts/{DX9DFxX2.chunk.js → DsM1bfoR.chunk.js} +2 -2
  236. package/dist/Assets/js/dist/scripts/{DX9DFxX2.chunk.js.map → DsM1bfoR.chunk.js.map} +1 -1
  237. package/dist/Assets/js/dist/scripts/{Dh3G-ann.chunk.js → Dt2TCPUI.chunk.js} +2 -2
  238. package/dist/Assets/js/dist/scripts/{Dh3G-ann.chunk.js.map → Dt2TCPUI.chunk.js.map} +1 -1
  239. package/dist/Assets/js/dist/scripts/{DA6Ynhan.chunk.js → DtylOK55.chunk.js} +2 -2
  240. package/dist/Assets/js/dist/scripts/{DA6Ynhan.chunk.js.map → DtylOK55.chunk.js.map} +1 -1
  241. package/dist/Assets/js/dist/scripts/{CJBiVila2.chunk.js → DuTcsFNo2.chunk.js} +2 -2
  242. package/dist/Assets/js/dist/scripts/{CJBiVila2.chunk.js.map → DuTcsFNo2.chunk.js.map} +1 -1
  243. package/dist/Assets/js/dist/scripts/{BBFS0f7w.chunk.js → Dw0mo6Cf.chunk.js} +2 -2
  244. package/dist/Assets/js/dist/scripts/{BBFS0f7w.chunk.js.map → Dw0mo6Cf.chunk.js.map} +1 -1
  245. package/dist/Assets/js/dist/scripts/{Cg5KHpRA.chunk.js → DwISzabN.chunk.js} +2 -2
  246. package/dist/Assets/js/dist/scripts/{Cg5KHpRA.chunk.js.map → DwISzabN.chunk.js.map} +1 -1
  247. package/dist/Assets/js/dist/scripts/{DMxtE2iS.chunk.js → DxW67uUT.chunk.js} +2 -2
  248. package/dist/Assets/js/dist/scripts/{DMxtE2iS.chunk.js.map → DxW67uUT.chunk.js.map} +1 -1
  249. package/dist/Assets/js/dist/scripts/{BOGS-BOS.chunk.js → Eg4zYYCO.chunk.js} +2 -2
  250. package/dist/Assets/js/dist/scripts/{BOGS-BOS.chunk.js.map → Eg4zYYCO.chunk.js.map} +1 -1
  251. package/dist/Assets/js/dist/scripts/{CSuC7le7.chunk.js → GT6nO4Jv.chunk.js} +2 -2
  252. package/dist/Assets/js/dist/scripts/{CSuC7le7.chunk.js.map → GT6nO4Jv.chunk.js.map} +1 -1
  253. package/dist/Assets/js/dist/scripts/{BhKv6dKl2.chunk.js → GpDEun8c2.chunk.js} +2 -2
  254. package/dist/Assets/js/dist/scripts/{BhKv6dKl2.chunk.js.map → GpDEun8c2.chunk.js.map} +1 -1
  255. package/dist/Assets/js/dist/scripts/{DKJC5qg0.chunk.js → OKjYL31I.chunk.js} +2 -2
  256. package/dist/Assets/js/dist/scripts/{DKJC5qg0.chunk.js.map → OKjYL31I.chunk.js.map} +1 -1
  257. package/dist/Assets/js/dist/scripts/{D8rrJ-jY2.chunk.js → OrCUhFjq2.chunk.js} +2 -2
  258. package/dist/Assets/js/dist/scripts/{D8rrJ-jY2.chunk.js.map → OrCUhFjq2.chunk.js.map} +1 -1
  259. package/dist/Assets/js/dist/scripts/{D3exV_Ay2.chunk.js → SVXAAhk02.chunk.js} +2 -2
  260. package/dist/Assets/js/dist/scripts/{D3exV_Ay2.chunk.js.map → SVXAAhk02.chunk.js.map} +1 -1
  261. package/dist/Assets/js/dist/scripts/{CcZKy7SH.chunk.js → SmmnJrec.chunk.js} +2 -2
  262. package/dist/Assets/js/dist/scripts/{CcZKy7SH.chunk.js.map → SmmnJrec.chunk.js.map} +1 -1
  263. package/dist/Assets/js/dist/scripts/{Dy4nscVE2.chunk.js → T3BageSw2.chunk.js} +2 -2
  264. package/dist/Assets/js/dist/scripts/{Dy4nscVE2.chunk.js.map → T3BageSw2.chunk.js.map} +1 -1
  265. package/dist/Assets/js/dist/scripts/{B8PM5Ji3.chunk.js → T6xxjp_W.chunk.js} +2 -2
  266. package/dist/Assets/js/dist/scripts/{B8PM5Ji3.chunk.js.map → T6xxjp_W.chunk.js.map} +1 -1
  267. package/dist/Assets/js/dist/scripts/{Cp6Af16p.chunk.js → Uc2eW092.chunk.js} +2 -2
  268. package/dist/Assets/js/dist/scripts/{Cp6Af16p.chunk.js.map → Uc2eW092.chunk.js.map} +1 -1
  269. package/dist/Assets/js/dist/scripts/{DmKyGgLu.chunk.js → XHoEdG1q.chunk.js} +2 -2
  270. package/dist/Assets/js/dist/scripts/{DmKyGgLu.chunk.js.map → XHoEdG1q.chunk.js.map} +1 -1
  271. package/dist/Assets/js/dist/scripts/{BdVoyBI02.chunk.js → Y14NYZ692.chunk.js} +2 -2
  272. package/dist/Assets/js/dist/scripts/{BdVoyBI02.chunk.js.map → Y14NYZ692.chunk.js.map} +1 -1
  273. package/dist/Assets/js/dist/scripts/{DrszevCi.chunk.js → Y_IcNhI9.chunk.js} +2 -2
  274. package/dist/Assets/js/dist/scripts/{DrszevCi.chunk.js.map → Y_IcNhI9.chunk.js.map} +1 -1
  275. package/dist/Assets/js/dist/scripts/{CMGpVYHd.chunk.js → Yr5eNz05.chunk.js} +2 -2
  276. package/dist/Assets/js/dist/scripts/{CMGpVYHd.chunk.js.map → Yr5eNz05.chunk.js.map} +1 -1
  277. package/dist/Assets/js/dist/scripts/{QnwProbJ2.chunk.js → Yrc9o6bG2.chunk.js} +2 -2
  278. package/dist/Assets/js/dist/scripts/{QnwProbJ2.chunk.js.map → Yrc9o6bG2.chunk.js.map} +1 -1
  279. package/dist/Assets/js/dist/scripts/{app-Dl-tzfIp.js → app-RphP4Ht0.js} +4 -4
  280. package/dist/Assets/js/dist/scripts/{app-Dl-tzfIp.js.map → app-RphP4Ht0.js.map} +1 -1
  281. package/dist/Assets/js/dist/scripts/{B96Bwi2D.chunk.js → cUgHqo-u.chunk.js} +2 -2
  282. package/dist/Assets/js/dist/scripts/{B96Bwi2D.chunk.js.map → cUgHqo-u.chunk.js.map} +1 -1
  283. package/dist/Assets/js/dist/scripts/{oGkpmMft2.chunk.js → dmUfJoJz2.chunk.js} +2 -2
  284. package/dist/Assets/js/dist/scripts/{oGkpmMft2.chunk.js.map → dmUfJoJz2.chunk.js.map} +1 -1
  285. package/dist/Assets/js/dist/scripts/{DjlPflaG.chunk.js → fapHSEex.chunk.js} +2 -2
  286. package/dist/Assets/js/dist/scripts/{DjlPflaG.chunk.js.map → fapHSEex.chunk.js.map} +1 -1
  287. package/dist/Assets/js/dist/scripts/{CaEXONXp2.chunk.js → jf0e_ii92.chunk.js} +2 -2
  288. package/dist/Assets/js/dist/scripts/{CaEXONXp2.chunk.js.map → jf0e_ii92.chunk.js.map} +1 -1
  289. package/dist/Assets/js/dist/scripts/{Co7TevGA.chunk.js → kp4jXqVv.chunk.js} +2 -2
  290. package/dist/Assets/js/dist/scripts/{Co7TevGA.chunk.js.map → kp4jXqVv.chunk.js.map} +1 -1
  291. package/dist/Assets/js/dist/scripts/lAvSm0ti.chunk.js +2 -0
  292. package/dist/Assets/js/dist/scripts/lAvSm0ti.chunk.js.map +1 -0
  293. package/dist/Assets/js/dist/scripts/{Dmf5vYc42.chunk.js → n7lzp_Mc2.chunk.js} +2 -2
  294. package/dist/Assets/js/dist/scripts/{Dmf5vYc42.chunk.js.map → n7lzp_Mc2.chunk.js.map} +1 -1
  295. package/dist/Assets/js/dist/scripts/{CG9yCT4r2.chunk.js → nvtWO4PW2.chunk.js} +2 -2
  296. package/dist/Assets/js/dist/scripts/{CG9yCT4r2.chunk.js.map → nvtWO4PW2.chunk.js.map} +1 -1
  297. package/dist/Assets/js/dist/scripts/{CACu0hGi2.chunk.js → oYKM19q12.chunk.js} +2 -2
  298. package/dist/Assets/js/dist/scripts/{CACu0hGi2.chunk.js.map → oYKM19q12.chunk.js.map} +1 -1
  299. package/dist/Assets/js/dist/scripts/{B5v11U7g.chunk.js → ohTu1tHz.chunk.js} +2 -2
  300. package/dist/Assets/js/dist/scripts/{B5v11U7g.chunk.js.map → ohTu1tHz.chunk.js.map} +1 -1
  301. package/dist/Assets/js/dist/scripts/{BrT-onLe2.chunk.js → uCRnfBEw2.chunk.js} +2 -2
  302. package/dist/Assets/js/dist/scripts/{BrT-onLe2.chunk.js.map → uCRnfBEw2.chunk.js.map} +1 -1
  303. package/dist/Assets/js/dist/scripts/{3XkTogZ22.chunk.js → udVWVmrH2.chunk.js} +2 -2
  304. package/dist/Assets/js/dist/scripts/{3XkTogZ22.chunk.js.map → udVWVmrH2.chunk.js.map} +1 -1
  305. package/dist/Assets/js/dist/scripts/{DW-yUqjB2.chunk.js → v0VARBBE2.chunk.js} +2 -2
  306. package/dist/Assets/js/dist/scripts/{DW-yUqjB2.chunk.js.map → v0VARBBE2.chunk.js.map} +1 -1
  307. package/dist/Assets/js/dist/scripts/{B4lIRWK22.chunk.js → vf9_5VGa2.chunk.js} +2 -2
  308. package/dist/Assets/js/dist/scripts/{B4lIRWK22.chunk.js.map → vf9_5VGa2.chunk.js.map} +1 -1
  309. package/dist/Assets/js/dist/scripts/{pOwOak4Z2.chunk.js → wTEWtWoE2.chunk.js} +2 -2
  310. package/dist/Assets/js/dist/scripts/{pOwOak4Z2.chunk.js.map → wTEWtWoE2.chunk.js.map} +1 -1
  311. package/dist/Assets/js/dist/scripts/{DPYIBfGB.chunk.js → xj8_Pfx7.chunk.js} +2 -2
  312. package/dist/Assets/js/dist/scripts/{DPYIBfGB.chunk.js.map → xj8_Pfx7.chunk.js.map} +1 -1
  313. package/dist/bundles.json +1 -1
  314. package/dist/en.json +1 -1
  315. package/package.json +1 -1
  316. package/dist/Assets/js/dist/scripts/D2iK_uRt.chunk.js +0 -2
  317. package/dist/Assets/js/dist/scripts/DBUreHJA.chunk.js +0 -3
  318. package/dist/Assets/js/dist/scripts/DBUreHJA.chunk.js.map +0 -1
  319. package/dist/Assets/js/dist/scripts/Dh5DbdtP.chunk.js +0 -2
  320. package/dist/Assets/js/dist/scripts/Dh5DbdtP.chunk.js.map +0 -1
  321. package/dist/Assets/js/dist/scripts/DrBVabtm.chunk.js +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"CixcMUHF.chunk.js","names":[],"sources":["../../../../../src/shared/flight-requests/WidgetRequests.ts","../../../../../../../libs/shared/src/flight-requests/AudienceRequests.ts","../../../../../../../libs/shared/src/components/back-button/BackButton.tsx","../../../../../../../libs/shared/src/context/BannerPortalContext.tsx","../../../../../../../libs/shared/src/components/banner-header/hooks/useBannerHeader.ts","../../../../../../../libs/shared/src/components/banner-header/default-banner-header/default-banner-header.module.scss","../../../../../../../libs/shared/src/components/banner-header/default-banner-header/DefaultBannerHeader.tsx","../../../../../../../libs/shared/src/components/video/Video.tsx","../../../../../../../libs/shared/src/images/svg/actions/PauseSvg.tsx","../../../../../../../libs/shared/src/images/svg/objects/LinkSvg.tsx","../../../../../../../libs/shared/src/components/banner-header/enums/VideoBannerControlOption.ts","../../../../../../../libs/shared/src/components/banner-header/utils/PartnerProfileBannerHeaderHelper.ts","../../../../../../../libs/shared/src/components/banner-header/partner-profile-banner-header/partner-profile-banner-header.module.scss","../../../../../../../libs/shared/src/components/banner-header/partner-profile-banner-header/PartnerProfileBannerHeaderContent.tsx","../../../../../../../libs/shared/src/components/banner-header/partner-profile-banner-header/PartnerProfileBannerHeader.tsx","../../../../../../../libs/shared/src/components/banner-header/BannerHeader.tsx","../../../../../../../libs/shared/src/hooks/useTransformer.tsx","../../../../../../../libs/shared/src/components/widgets/curated-widgets/hooks/useInfiniteWidgetFetch.ts","../../../../../../../libs/shared/src/components/widgets/curated-widgets/InfiniteWidgetContainerView.tsx","../../../../../../../libs/shared/src/hooks/useEmptyWidgets.ts","../../../../../../../libs/shared/src/hooks/useExpandableTextButton.ts","../../../../../../../libs/shared/src/components/expandable-text-inline/expandable-text-inline.module.scss","../../../../../../../libs/shared/src/components/expandable-text-inline/ExpandableTextInline.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/channel-dashboard-description/ChannelDashboardDescription.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-dashboard-coming-soon/ContentPartnerDashboardComingSoon.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-dashboard-content-region/ContentPartnerDashboardContentRegion.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-dashboard-no-content/ContentPartnerDashboardNoContent.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-empty-state/ContentPartnerEmptyState.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/ContentPartnerDashboard.tsx","../../../../../../../libs/shared/src/apps/discover/components/header/discover-header.module.scss","../../../../../../../libs/shared/src/apps/discover/components/header/DiscoverHeader.tsx","../../../../../../../libs/shared/src/apps/discover/components/tutorial-videos/TutorialVideoWidget.tsx","../../../../../../../libs/shared/src/components/widgets/countdown/countdown.module.scss","../../../../../../../libs/shared/src/components/widgets/countdown/CountdownWidget.tsx","../../../../../../../libs/shared/src/components/widgets/countdown/CountdownContainer.tsx","../../../../../../../libs/shared/src/components/widgets/countdown/events/commonwealth-game.ts","../../../../../../../libs/shared/src/apps/discover/components/discover-dashboard/empty-state/DiscoverDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/discover/components/discover-dashboard/DiscoverDashboard.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/company-dashboard/empty-state/CompanyDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/company-dashboard/CompanyDashboard.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/exchange-and-tv-links/exchange-and-tv-links.module.scss","../../../../../../../libs/shared/src/apps/movies-and-tv/components/exchange-and-tv-links/ExchangeAndTvLinks.tsx","../../../../../../../libs/shared/src/flight-requests/ProductRequests.ts","../../../../../../../libs/shared/src/hooks/UseProducts.ts","../../../../../../../libs/shared/src/apps/movies-and-tv/components/movies-and-tv-dashboard/empty-state/MoviesAndTvDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/movies-and-tv-dashboard/movies-and-tv-dashboard.module.scss","../../../../../../../libs/shared/src/apps/movies-and-tv/components/movies-and-tv-dashboard/MoviesAndTvDashboard.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/company-dashboard/empty-state/StreamableCompanyDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/subjects/components/audience-item/audience-item.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/audience-item/AudienceItem.tsx","../../../../../../../libs/shared/src/apps/subjects/components/audience-filter/AudienceFilter.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/company-dashboard/StreamableCompanyDashboard.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/header/streamable-header.module.scss","../../../../../../../libs/shared/src/apps/streamable-learning/components/header/StreamableHeader.tsx","../../../../../../../libs/shared/src/hooks/usePermissions.ts","../../../../../../../libs/shared/src/apps/streamable-learning/components/dashboard/empty-state/StreamableDiscoverDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState.tsx","../../../../../../../libs/shared/src/components/table-of-contents-list/table-of-contents-list.module.scss","../../../../../../../libs/shared/src/components/table-of-contents-list/TableOfContentsList.tsx","../../../../../../../libs/shared/src/images/svg/objects/TableOfContentsSvg.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/table-of-contents.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState.tsx","../../../../../../../libs/shared/src/flight-requests/DashboardRequests.ts","../../../../../../../libs/shared/src/apps/subjects/hooks/useGetTopicsWidgets.ts","../../../../../../../libs/shared/src/hooks/useTableOfContentsActiveHeading.tsx","../../../../../../../libs/shared/src/hooks/useTableOfContentsScroll.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-coming-soon/ClassificationComingSoon.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/audiences/ClassificationDashboardAudiences.tsx","../../../../../../../libs/shared/src/apps/subjects/hooks/useDirectoryTabProductTipSwitcher.ts","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/classification-tabs.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/ClassificationTabs.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-dashboard-nav/ClassificationDashboardNav.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/ClassificationDashboard.tsx","../../../../../src/apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/dashboard-status-badge.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge.tsx","../../../../../src/apps/dashboard-editor/components/dashboard-sticky-header/dashboard-sticky-header.module.scss","../../../../../src/apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader.tsx","../../../../../src/apps/dashboard-editor/components/loading-mask/loading-mask.module.scss","../../../../../src/apps/dashboard-editor/components/loading-mask/LoadingMask.tsx","../../../../../src/shared/components/drop-indicator/drop-indicator.module.scss","../../../../../src/shared/components/drop-indicator/DropIndicator.tsx","../../../../../src/apps/dashboard-editor/components/dashboard-widget-icon/DashboardWidgetIcon.tsx","../../../../../src/apps/dashboard-editor/components/widget-editor-item/widget-editor-item.module.scss","../../../../../src/apps/dashboard-editor/components/widget-editor-item/WidgetEditorItem.tsx","../../../../../src/apps/dashboard-editor/components/widget-editor-list/widget-editor-list.module.scss","../../../../../src/apps/dashboard-editor/components/widget-editor-list/WidgetEditorList.tsx","../../../../../src/apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-dashboard-view.module.scss","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-classification-dashboard/EditClassificationDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-company-dashboard/EditCompanyDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-content-partner-dashboard/EditContentPartnerDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-discover-dashboard/EditDiscoverDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-movies-and-tv-dashboard/EditMoviesAndTvDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/EditDashboardContainerView.tsx"],"sourcesContent":["import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/flight';\n\nimport { CuratedDashboard, CuratedWidget } from 'libs/shared/interfaces';\n\nexport const WidgetRequests = {\n sortWidgets(\n widgets: CuratedWidget[],\n dashboard: CuratedDashboard,\n success?: (data: CuratedWidget[]) => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n const dashboardKey = `dashboard:${dashboard.id}`;\n\n return {\n url: '/api/discover/v1/widgets/bulk',\n key: 'widgets:bulk',\n type: HttpVerbs.PUT,\n data: widgets,\n success,\n error,\n always,\n normalize: false,\n invalidationKeys: dashboardKey\n };\n }\n};\n","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\n\nexport const AudienceRequests = {\n presentationAudiences(presentationType: PresentationType, presentationId?: string): Flight.PublicRequest {\n const requestOpts = {\n type: presentationType\n };\n\n return {\n bootstrapName: 'presentationAudiences',\n url: UrlHelper.urlBuilder('{gateway}/v1/users/me/audiences', requestOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/subjects/presentation/${presentationId}/audiences`, requestOpts),\n regionScoped: true,\n key: `presentation:audiences:${presentationId}:${presentationType}`,\n normalize: false\n };\n },\n\n audiencesByPresentationId(presentationId: string): Flight.PublicRequest {\n return {\n url: `{gateway}/v1/subjects/presentations/${presentationId}/audiences`,\n publicUrl: UrlHelper.urlBuilder(`/api/subjects/presentation/${presentationId}/audiences`, {\n type: PresentationType.Subject.toLowerCase(),\n presentationId\n }),\n key: `presentation:${presentationId}:audiences`,\n normalize: false\n };\n }\n};\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ChevronLeftSvg } from 'libs/shared/images/svg/arrows/ChevronLeftSvg';\n\nconst namespace = 'shared.backButton';\n\ninterface BackButtonProps {\n appLink: Core.AppLink;\n backToName?: string;\n color?: 'black' | 'white';\n extraClasses?: string;\n /**\n * Whether or not the button text has a text shadow. Defaults to true\n */\n textShadow?: boolean;\n}\n\nBackButton.defaultProps = {\n color: 'black',\n extraClasses: ''\n};\n\nexport function BackButton(props: BackButtonProps): React.ReactElement {\n const { backToName, appLink, color, extraClasses, textShadow } = {\n textShadow: true,\n ...props\n };\n\n const backPhrase = backToName ?\n LanguageService.getPhrase(namespace, 'backTo', { backToName }) :\n LanguageService.getPhrase(namespace, 'back');\n\n const colorClass = color === 'black' ? '' : 'text-white';\n const textShadowClass = textShadow ? 'text-shadow' : '';\n\n return (\n <AppLink\n appLink={appLink}\n className={`d-inline-flex align-items-center h5 mb-0 ${extraClasses} ${colorClass} ${textShadowClass}`}\n >\n <SvgContainer svg={ChevronLeftSvg} size={SvgContainerSize.Medium} />\n <span className='ms-1'>{backPhrase}</span>\n </AppLink>\n );\n}\n","import React from 'react';\n\nfunction getContainer(className: string): Element {\n return document.querySelector(`.${className}`);\n}\n\nexport interface BannerPortalContent {\n container: Element | null;\n}\n\nexport const BannerPortalContext = React.createContext<BannerPortalContent>(null);\n\ntype BannerPortalContextProviderProps = React.PropsWithChildren<{\n containerClassName: string\n}>;\n\nexport function BannerPortalContextProvider(props: BannerPortalContextProviderProps): JSX.Element {\n const [ container, setContainer ] = React.useState<Element>();\n\n React.useEffect(() => {\n setContainer(getContainer(props.containerClassName));\n }, []);\n\n return (\n <BannerPortalContext.Provider value={{ container }}>\n {props.children}\n </BannerPortalContext.Provider>\n );\n}\n","import React from 'react';\n\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { ImageMinDimensions } from 'libs/shared/constants/ImageSizes';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ImageSize, ImageType, ResizeType } from 'libs/shared/enums/Images';\nimport { Breakpoints, useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Banner, Logo } from 'libs/shared/interfaces';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nconst RATIO = `${ImageMinDimensions[ImageType.Banners].width}:${ImageMinDimensions[ImageType.Banners].height}`;\nconst DEFAULT_WIDTH = 1200; // This is ImageSize.Large for a Banner.\nconst LARGE_SCREEN_WIDTH = 1920;\n\nfunction getImageWidth(breakpoints: Breakpoints): number {\n if (breakpoints.xxl) return LARGE_SCREEN_WIDTH;\n\n return DEFAULT_WIDTH;\n}\n\ntype ContainerProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;\n\nfunction getContainerProps(\n banner?: Banner,\n bannerUrl?: string,\n bannerClassName?: string,\n blockColourClass?: string\n): ContainerProps {\n const containerProps: ContainerProps = {\n className: `banner banner-header ${bannerClassName}`,\n style: bannerUrl ? { backgroundImage: `url('${bannerUrl}')` } : {}\n };\n\n if (!banner && blockColourClass) {\n delete containerProps.style;\n containerProps.className += ` ${blockColourClass}`;\n }\n\n return containerProps;\n}\n\ninterface UseBannerHeaderOptions {\n heading: string;\n\n logo?: Logo;\n banner?: Banner;\n imageCdnUrl?: string;\n bannerImageOptions?: ImageOptions;\n bannerClassName?: string;\n blockColourClass?: string;\n}\n\nexport function useBannerHeader(options: UseBannerHeaderOptions) {\n const { heading, banner, logo, imageCdnUrl, bannerClassName, blockColourClass } = options;\n\n const breakpoints = useBreakpoints();\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n const imageWidth = getImageWidth(breakpoints);\n\n const bannerImageOptions = options.bannerImageOptions || {\n width: imageWidth,\n ratio: RATIO,\n resizeType: ResizeType.Cover\n };\n\n const bannerUrl =\n !!banner && !!imageCdnUrl ?\n ImageHelper.createBannerUrl(\n banner,\n {\n fallbackBaseUrl: imageCdnUrl,\n fallbackCategoryName: heading,\n type: ImageType.Banners\n },\n bannerImageOptions\n ) :\n undefined;\n\n const logoFallbackBgClassName = getBgColorClass(heading, BG_COLOUR_CLASS_NAMES);\n const logoUrl = !!logo && !!imageCdnUrl ? ImageHelper.createUrl(logo.url, { size: ImageSize.Medium }) : undefined;\n const containerProps = getContainerProps(banner, bannerUrl, bannerClassName, blockColourClass);\n\n return {\n logoUrl,\n bannerUrl,\n containerProps,\n portalContainerContext,\n logoFallbackBgClassName\n };\n}\n","@import '~styles/utils/mixins';\n@import '~styles/utils/include-media';\n:local {\n .bannerContent {\n position: absolute;\n bottom: map-get($spacers, 3);\n right: map-get($spacers, 3);\n left: map-get($spacers, 3);\n display: flex;\n align-items: flex-end;\n\n .actionsContainer {\n margin-left: auto;\n padding-left: map-get($spacers, 2);\n }\n\n @include media('<=md') {\n bottom: 1rem;\n }\n }\n\n .bannerContentWithLogo {\n right: 7rem + map-get($spacers, 3);\n }\n\n .container {\n @include media('<=xl') {\n max-width: 100%;\n }\n }\n\n .logoContainer {\n position: absolute;\n top: 50%;\n right: map-get($spacers, 3);\n transform: translateY(-50%);\n height: 60%;\n max-height: 7.5rem;\n\n img {\n height: 100%;\n }\n }\n\n .logoContainerLeft {\n width: 8rem;\n aspect-ratio: 1 / 1;\n }\n\n .logoHeading {\n max-width: 32.5rem;\n }\n\n .specialEventContainer {\n font-size: 0.8rem;\n min-width: 7rem;\n margin-right: map-get($spacers, 3);\n\n @include media('<=lg') {\n min-width: 6rem;\n font-size: 0.7rem;\n margin-right: map-get($spacers, 2);\n }\n\n @include media('<=md') {\n min-width: 5.5rem;\n font-size: 0.65rem;\n }\n\n @include media('<=sm') {\n min-width: 5rem;\n font-size: 0.6rem;\n }\n }\n\n .headingLarge {\n @include clamp(5);\n font-size: $h3-font-size;\n\n @include media(\"<xl\") {\n font-size: $h4-font-size;\n }\n\n @include media(\"<lg\") {\n @include clamp(4);\n font-size: $h5-font-size;\n }\n\n @include media(\"<md\") {\n font-size: $h6-font-size;\n }\n }\n .heading {\n @include clamp(4);\n \n @include media(\"<=sm\") {\n @include clamp(2);\n }\n \n }\n}","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ComingSoonTag } from 'libs/shared/apps/calendar/components/coming-soon-tag/ComingSoonTag';\nimport { GenericCalendarDate } from 'libs/shared/apps/calendar/components/generic-calendar-date/GenericCalendarDate';\nimport { CalendarTheme } from 'libs/shared/apps/calendar/interfaces/CalendarTheme';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { BackButton } from 'libs/shared/components/back-button/BackButton';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { Banner, CalendarEvent, Logo } from 'libs/shared/interfaces';\nimport { ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport { useBannerHeader } from '../hooks/useBannerHeader';\n\nimport styles from './default-banner-header.module.scss';\n\nfunction getSizeClass(heading: string): string {\n if (heading.length < 160)\n return 'h1';\n\n return styles.headingLarge;\n}\n\nexport interface DefaultBannerHeaderProps {\n heading: string;\n banner?: Banner;\n bannerClassName?: string;\n imageCdnUrl?: string;\n logo?: Logo;\n logoBgColour?: string;\n actions?: ActionOptions[];\n specialEvent?: CalendarEvent;\n backButtonAppLink?: Core.AppLink;\n backButtonText?: string;\n backButtonClasses?: string;\n sortComponent?: JSX.Element;\n blockColourClass?: string;\n actionsDropdownClassName?: string;\n detailsComponent?: () => React.ReactElement;\n imageOptions?: ImageOptions;\n showComingSoon?: boolean;\n alignLogoLeft?: boolean;\n calendarTheme?: CalendarTheme;\n}\n\nconst namespace = 'shared.defaultBannerHeader';\n\nexport const DefaultBannerHeader =\n React.memo(function(props: React.PropsWithChildren<DefaultBannerHeaderProps>): React.ReactElement {\n const { heading, banner, imageCdnUrl, actions, sortComponent, blockColourClass, specialEvent } = props;\n\n const {\n logoUrl,\n portalContainerContext,\n logoFallbackBgClassName,\n containerProps\n } = useBannerHeader({\n heading,\n banner,\n blockColourClass,\n bannerClassName: props.bannerClassName,\n imageCdnUrl,\n logo: props.logo,\n bannerImageOptions: props.imageOptions\n });\n\n const specialEventIsToday = React.useMemo(() => {\n if (!specialEvent || props.showComingSoon)\n return false;\n\n const today = DateHelper.format(new Date(), 'YYYY-MM-DD');\n\n if (!specialEvent.endDate)\n return specialEvent.startDate === today;\n\n return specialEvent.startDate <= today && specialEvent.endDate >= today;\n }, [specialEvent]);\n\n function getSpecialEventMonthText(specialEvent: CalendarEvent): string {\n if (!specialEvent.endDate)\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n if (DateHelper.isSame(specialEvent.startDate, specialEvent.endDate, 'month'))\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n return `${DateHelper.format(specialEvent.startDate, 'MMM')} - ${DateHelper.format(specialEvent.endDate, 'MMM')}`;\n }\n\n const DetailsComponent = props.detailsComponent;\n\n return PortalHelper.renderInPortalIfExists(\n // \"banner\" is used in playlists in Online. banner-header is used by all other projects\n <header {...containerProps}>\n <div className={`container ${styles.container} position-relative inner-banner`}>\n {props.backButtonAppLink && (\n <div className='pt-3'>\n <BackButton\n appLink={props.backButtonAppLink}\n backToName={props.backButtonText}\n extraClasses={props.backButtonClasses}\n color='white'\n />\n </div>\n )}\n \n <div className={`${props.alignLogoLeft ? 'position-absolute top-50 start-0 translate-middle-y w-100 ps-4' : `${styles.bannerContent} px-2 ${props.logo?.url ? styles.bannerContentWithLogo : ''}`}`}>\n {!!specialEvent && (\n <div className={`position-relative ${styles.specialEventContainer}`}>\n <GenericCalendarDate\n body={{\n type: specialEvent.endDate ? 'range' : 'day',\n text: specialEvent.endDate ?\n `${DateHelper.format(specialEvent.startDate, 'DD')}-${DateHelper.format(specialEvent.endDate, 'DD')}` :\n DateHelper.format(specialEvent.startDate, 'DD')\n }}\n month={getSpecialEventMonthText(specialEvent)}\n theme={props.calendarTheme}\n />\n </div>\n )}\n <div>\n {specialEventIsToday && (\n <div className='rounded-pill py-1 px-2 my-1 me-1 fw-semibold bg-light-blue lh-1 d-inline-block'>\n <Text namespace={namespace} phrase='onToday' />\n </div>\n )}\n {props.showComingSoon && (\n <ComingSoonTag className='pe-2 fw-semibold mb-1 rounded-pill justify-content-start text-nowrap' />\n )}\n <div className='d-flex align-items-center'>\n {props.alignLogoLeft && props.logo?.url &&\n <div className={`${styles.logoContainerLeft} d-none d-md-block rounded-circle overflow-hidden me-3 ${logoFallbackBgClassName}`}>\n <LazyImage\n src={logoUrl}\n style={{ backgroundColor: props.logoBgColour }}\n />\n </div>\n }\n <h1 className={`text-white text-shadow pe-3 position-static ${styles.heading} ${getSizeClass(heading)} ${props.alignLogoLeft ? 'w-50' : ''}`}>\n {heading}\n {DetailsComponent && <DetailsComponent />}\n </h1>\n </div>\n </div>\n {!!actions && (\n <div className={styles.actionsContainer}>\n <Actions\n actions={actions}\n sortComponent={sortComponent}\n actionsDropdownClassName={props.actionsDropdownClassName}\n />\n </div>\n )}\n </div>\n {!props.alignLogoLeft && !!props.logo?.url &&\n <div className={styles.logoContainer}>\n <img\n src={logoUrl}\n className='rounded-circle'\n />\n </div>\n }\n </div>\n </header>,\n portalContainerContext?.container\n );\n }, (prevProps, nextProps): boolean => (\n prevProps.actions === nextProps.actions\n && prevProps.heading === nextProps.heading\n && prevProps.logo?.url === nextProps.logo?.url\n ));\n\nexport function PartialDefaultBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className={`partial-banner partial-loading-background ${styles.banner}`} />,\n portalContainerContext?.container\n );\n}\n","import React from 'react';\n\nimport { ContentPartnerEventLoggerFn } from 'libs/shared/apps/content-partners/utils/get-content-partner-event-logger/getContentPartnerEventLogger';\n\ninterface VideoState {\n loaded: boolean;\n isPlaying: boolean;\n isFinished: boolean;\n}\n\ninterface VideoControlsProps {\n onPlay?: () => void;\n onPause?: () => void;\n onEnd?: () => void;\n onInit?: () => void;\n onMute?: () => void;\n onUnmute?: () => void;\n /**\n * Milliseconds to delay the the `loaded` state being set to true.\n */\n addDelayOnLoad?: number;\n log?: ContentPartnerEventLoggerFn;\n}\n\nexport function useVideoControls(options?: VideoControlsProps) {\n const ref = React.useRef<HTMLVideoElement>(null);\n\n const [ videoState, setVideoState ] = React.useState<VideoState>({\n loaded: false,\n isPlaying: false,\n // Note: If `loop` is set to true, then `isFinished` will never be true.\n isFinished: false\n });\n\n function setVideoStateProperty<K extends keyof VideoState>(key: K, value: VideoState[K]) {\n setVideoState(prevState => ({ ...prevState, [key]: value }));\n }\n\n const videoEventListenerMap: {[key in keyof HTMLVideoElementEventMap]?: (event: Event) => void } = {\n loadstart: () => {\n options?.onInit?.();\n },\n canplay: () => {\n if (typeof options?.addDelayOnLoad === 'number') {\n pause();\n if (ref.current?.autoplay)\n ref.current.autoplay = false;\n \n setTimeout(() => {\n setVideoStateProperty('loaded', true);\n play();\n }, options.addDelayOnLoad);\n } else {\n setVideoStateProperty('loaded', true);\n }\n },\n play: () => {\n setVideoStateProperty('isPlaying', true);\n options?.onPlay?.();\n },\n pause: () => {\n setVideoStateProperty('isPlaying', false);\n options?.onPause?.();\n },\n ended: () => {\n setVideoState(prevState => ({ ...prevState, isPlaying: false, isFinished: true }));\n options?.onEnd?.();\n }\n };\n\n React.useEffect(() => {\n if (!Object.keys(videoEventListenerMap).length)\n return;\n\n Object.entries(videoEventListenerMap).forEach(([ event, handler ]) => {\n ref.current?.addEventListener(event, handler);\n });\n\n return () => {\n Object.entries(videoEventListenerMap).forEach(([ event, handler ]) => {\n ref.current?.removeEventListener(event, handler);\n });\n };\n }, [ref.current]);\n\n function play() {\n if (videoState.isPlaying)\n return;\n \n ref.current?.play();\n setVideoState(prevState => ({ ...prevState, isPlaying: true, isFinished: false }));\n }\n\n function pause() {\n if (!videoState.isPlaying)\n return;\n \n ref.current?.pause();\n setVideoStateProperty('isPlaying', false);\n }\n\n function togglePlayPause() {\n if (videoState.isPlaying) {\n pause();\n options?.log?.({\n type: 'click-video-banner-controls',\n control: 'pause'\n });\n } else {\n play();\n options?.log?.({\n type: 'click-video-banner-controls',\n control: 'play'\n });\n }\n }\n\n function loop() {\n if (!ref.current)\n return;\n \n ref.current.loop = true;\n }\n\n return {\n videoRef: ref,\n ...videoState,\n play,\n pause,\n togglePlayPause,\n loop\n };\n}\n\ninterface VideoProps extends React.VideoHTMLAttributes<HTMLVideoElement> {\n}\n\nexport const Video = React.forwardRef<HTMLVideoElement, VideoProps>((props, ref) => {\n const {\n autoPlay = false,\n muted = true,\n loop = false,\n controls = false,\n disablePictureInPicture = true,\n disableRemotePlayback = true,\n ...otherProps\n } = props;\n\n return (\n <video\n ref={ref}\n autoPlay={autoPlay}\n muted={muted}\n loop={loop}\n controls={controls}\n disablePictureInPicture={disablePictureInPicture}\n disableRemotePlayback={disableRemotePlayback}\n {...otherProps}\n />\n );\n});\n","import React from 'react';\n\nexport function PauseSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fillRule='evenodd'\n clipRule='evenodd'\n d='M9.5 6C8.67157 6 8 6.67157 8 7.5V16.5C8 17.3284 8.67157 18 9.5 18C10.3284 18 11 17.3284 11 16.5V7.5C11 6.67157 10.3284 6 9.5 6ZM15.5 6C14.6716 6 14 6.67157 14 7.5V16.5C14 17.3284 14.6716 18 15.5 18C16.3284 18 17 17.3284 17 16.5V7.5C17 6.67157 16.3284 6 15.5 6Z'\n />\n </svg>\n\n );\n}\n","import React from 'react';\n\nexport function LinkSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M17.834 5.916a2.5 2.5 0 0 0-3.536 0L12.53 7.684a.5.5 0 0 1-.707-.707l1.768-1.768a3.5 3.5 0 1 1 4.95 4.95l-3.687 3.687a3.786 3.786 0 0 1-5.354 0l-.152-.152a.5.5 0 0 1 .707-.707l.152.152a2.786 2.786 0 0 0 3.94 0l3.687-3.687a2.5 2.5 0 0 0 0-3.536m-8.94 3.99a3.643 3.643 0 0 1 5.152 0l.606.607a.5.5 0 1 1-.707.707l-.607-.606a2.643 2.643 0 0 0-3.737 0l-3.435 3.434a2.5 2.5 0 1 0 3.536 3.536l1.414-1.415a.5.5 0 0 1 .707.707l-1.414 1.415a3.5 3.5 0 1 1-4.95-4.95z'\n />\n </svg>\n );\n}\n","export enum VideoBannerControlOption {\n PlayPause = 'play-pause',\n WebsiteLink = 'website-link'\n}\n\nexport const AllVideoBannerControlOptions: VideoBannerControlOption[] = [\n VideoBannerControlOption.PlayPause,\n VideoBannerControlOption.WebsiteLink\n];\n","import { VideoBannerControlOption } from '../enums/VideoBannerControlOption';\n\nexport type PartnerProfileBannerHeaderContentType = 'text' | 'logo' | 'sign-up' | 'logo-with-name';\n\ninterface GetBannerHeaderContentTypeOptions {\n logoUrl?: string;\n isAuthenticated: boolean;\n showVideoBanner: boolean;\n isChannelTopic?: boolean;\n}\n\nexport const PartnerProfileBannerHeaderHelper = {\n getBannerHeaderContentType(\n options: GetBannerHeaderContentTypeOptions\n ): PartnerProfileBannerHeaderContentType {\n if (options.isChannelTopic)\n return 'logo-with-name';\n\n let contentType: PartnerProfileBannerHeaderContentType = 'text';\n\n if (options.logoUrl)\n contentType = 'logo';\n\n if (!options.isAuthenticated && options.showVideoBanner)\n contentType = 'sign-up';\n\n return contentType;\n },\n\n showWebsiteLinkControls(controls: VideoBannerControlOption[], websiteUrl: string, isStudent: boolean) {\n if (isStudent)\n return false;\n\n return !!websiteUrl && controls.includes(VideoBannerControlOption.WebsiteLink);\n }\n};\n","@import '~styles/utils/mixins';\n@import '~styles/utils/include-media';\n\n:local {\n $logoContainerWidth: 13.75rem; // 220px From design and what looks good\n $logoPositionBottomOffset: 1rem; // 16px offset\n\n .videoBannerRadius {\n border-radius: 0;\n\n @include media('>=xl') {\n border-radius: $border-radius-lg;\n }\n }\n\n .nowrap {\n white-space: nowrap;\n }\n\n\n .hasLogo {\n padding-bottom: $logoPositionBottomOffset;\n }\n\n .logoPosition {\n bottom: -$logoPositionBottomOffset;\n }\n\n .logoContainer {\n width: $logoContainerWidth;\n }\n\n .container {\n @include media('<=xl') {\n max-width: 100%;\n }\n }\n\n .signUpContainer {\n $leftOffset: $logoContainerWidth + map-get($spacers, 4);\n left: calc(#{$leftOffset});\n width: calc(100% - #{$leftOffset} - map-get($spacers, 1));\n z-index: 1;\n }\n\n .signUpContent {\n @include bg-blur(10px, true);\n border-left: none;\n border-right: none;\n }\n\n .signUpHeading {\n white-space: nowrap;\n\n @include media('<=md') {\n white-space: normal;\n }\n }\n\n .emailInput {\n @include media('>=md') {\n min-width: 19.375rem; // from design\n }\n }\n\n .videoControls {\n top: 1rem;\n right: 1rem;\n transition: opacity 0.5s ease-in-out;\n }\n\n .videoContent {\n opacity: 0;\n transition: opacity 0.5s ease-in-out;\n }\n\n .videoVisible {\n opacity: 1;\n }\n}","import React from 'react';\nimport { Button } from 'react-bootstrap';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { RectangularLogo } from 'libs/shared/components/rectangular-logo/RectangularLogo';\n\nimport { PartnerProfileBannerHeaderContentType } from '../utils/PartnerProfileBannerHeaderHelper';\n\nimport styles from './partner-profile-banner-header.module.scss';\n\nconst namespace = 'bannerHeader.partnerProfileBannerHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface PartnerProfileBannerHeaderContentProps {\n type: PartnerProfileBannerHeaderContentType;\n name: string;\n onClickSignUp?: (email: string) => void;\n logoUrl?: string;\n bgColor?: string;\n}\n\nfunction BannerWithText(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className='position-absolute bottom-0 start-0 mb-3 w-100 px-4'>\n <div className='d-flex align-items-center'>\n <h1 className='text-white text-shadow pe-3 position-static mb-0'>{props.name}</h1>\n </div>\n </div>\n </div>\n );\n}\n\nfunction BannerWithLogo(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className={classNames('position-absolute start-0 px-4', styles.logoPosition)}>\n <div className={styles.logoContainer}>\n <RectangularLogo\n logoUrl={props.logoUrl}\n bgColor={props.bgColor}\n name={props.name}\n classNames={{\n container: 'border border-white'\n }}\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction BannerWithLogoAndName(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className={classNames(\n 'position-absolute start-0 px-4 d-flex align-items-center gap-3',\n styles.logoPosition\n )}>\n <div className={styles.logoContainer}>\n <RectangularLogo\n logoUrl={props.logoUrl}\n bgColor={props.bgColor}\n name={props.name}\n classNames={{\n container: 'border border-white'\n }}\n />\n </div>\n <h1 className='text-white text-shadow mb-0'>{props.name}</h1>\n </div>\n </div>\n );\n}\n\nfunction BannerWithSignUp(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n const [ email, setEmail ] = React.useState('');\n\n function onSubmit(e: React.FormEvent<HTMLFormElement>): void {\n e.preventDefault();\n props.onClickSignUp?.(email);\n }\n\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className={classNames('position-absolute start-0 px-4 ', styles.logoPosition)}>\n <div className={styles.logoContainer}>\n <RectangularLogo\n logoUrl={props.logoUrl}\n bgColor={props.bgColor}\n name={props.name}\n classNames={{\n container: 'border border-white'\n }}\n />\n </div>\n </div>\n <div\n className={classNames(\n 'position-absolute bottom-0 pb-2 pb-md-3 px-0 px-sm-3 d-none d-xl-block',\n styles.signUpContainer\n )}\n >\n <div\n className={classNames(\n 'd-flex align-items-center justify-content-between gap-2 flex-wrap rounded-3 p-3',\n styles.signUpContent\n )}\n >\n <div className='d-sm-flex align-items-center gap-2 '>\n <h4 className={classNames('text-white text-shadow mb-0', styles.signUpHeading)}>\n {getPhrase('description')}\n </h4>\n </div>\n <form className='d-flex align-items-center gap-2 flex-grow-1 flex-md-grow-0' onSubmit={onSubmit}>\n <input\n type='email'\n className={classNames('form-control w-100', styles.emailInput)}\n placeholder={getPhrase('emailPlaceholder')}\n value={email}\n onChange={e => setEmail(e.target.value)}\n />\n <Button type='submit' variant='dark' className={styles.nowrap}>\n {getPhrase('cta')}\n </Button>\n </form>\n </div>\n </div>\n </div>\n );\n}\n\nconst HeaderTypeContentMap: Record<\n PartnerProfileBannerHeaderContentType,\n React.ComponentType<PartnerProfileBannerHeaderContentProps>\n> = {\n 'logo': BannerWithLogo,\n 'logo-with-name': BannerWithLogoAndName,\n 'sign-up': BannerWithSignUp,\n 'text': BannerWithText\n};\n\nexport function PartnerProfileBannerHeaderContent(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n const ContentComponent = HeaderTypeContentMap[props.type];\n return <ContentComponent {...props} />;\n}\n","import React from 'react';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ContentPartnerEventLoggerFn } from 'libs/shared/apps/content-partners/utils/get-content-partner-event-logger/getContentPartnerEventLogger';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { useVideoControls, Video } from 'libs/shared/components/video/Video';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ResizeType } from 'libs/shared/enums/Images';\nimport { PauseSvg } from 'libs/shared/images/svg/actions/PauseSvg';\nimport { PlaySvg } from 'libs/shared/images/svg/actions/PlaySvg';\nimport { LinkSvg } from 'libs/shared/images/svg/objects/LinkSvg';\nimport { Banner, Logo } from 'libs/shared/interfaces';\n\nimport { AllVideoBannerControlOptions, VideoBannerControlOption } from '../enums/VideoBannerControlOption';\nimport { useBannerHeader } from '../hooks/useBannerHeader';\nimport { PartnerProfileBannerHeaderHelper } from '../utils/PartnerProfileBannerHeaderHelper';\n\nimport { PartnerProfileBannerHeaderContent } from './PartnerProfileBannerHeaderContent';\n\nimport styles from './partner-profile-banner-header.module.scss';\n\nconst namespace = 'bannerHeader.partnerProfileBannerHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface VideoBannerContentProps {\n videoUrl: string;\n className?: string;\n videoRef: React.RefObject<HTMLVideoElement>;\n loop?: boolean;\n}\n\nfunction VideoBannerContent(props: VideoBannerContentProps): JSX.Element {\n return (\n <div className={classNames('position-absolute top-0 start-0 w-100 h-100 overflow-hidden', props.className, styles.videoBannerRadius)}>\n <Video ref={props.videoRef} autoPlay muted controls={false} loop={props.loop} className='w-100 h-100 object-fit-cover position-relative'>\n <source src={props.videoUrl} type='video/mp4' />\n </Video>\n </div>\n );\n}\n\ninterface VideoBannerControlsProps {\n isPlaying: boolean;\n togglePlayPause: () => void;\n className?: string;\n controls?: VideoBannerControlOption[];\n websiteUrl?: string;\n isStudent: boolean;\n log?: ContentPartnerEventLoggerFn;\n}\n\nfunction VideoBannerControls(props: VideoBannerControlsProps): JSX.Element {\n const PlayPauseIcon = props.isPlaying ? PauseSvg : PlaySvg;\n\n function onClickWebsiteLink(): void {\n if (!props.websiteUrl) return;\n LocationUtils.PageLoad(props.websiteUrl, true);\n props.log?.({\n type: 'click-video-banner-controls',\n control: 'website-link'\n });\n }\n \n const controls = props.controls || AllVideoBannerControlOptions;\n const showWebsiteLinkControls = PartnerProfileBannerHeaderHelper.showWebsiteLinkControls(\n controls,\n props.websiteUrl,\n props.isStudent\n );\n\n return (\n <div className={classNames(\n styles.videoControls,\n 'position-absolute d-flex gap-2 ',\n props.isPlaying && 'banner-header-video--controls',\n props.className\n )}>\n {showWebsiteLinkControls && (\n <IconButton\n svg={LinkSvg}\n svgSize={SvgContainerSize.Standard}\n className='bg-gray-200 rounded-circle cursor-pointer'\n onClick={onClickWebsiteLink}\n ariaLabel={getPhrase('viewWebsite')}\n role='button'\n tooltip={getPhrase('viewWebsite')}\n tooltipTrigger={[ 'hover', 'focus' ]}\n />\n )}\n {controls.includes(VideoBannerControlOption.PlayPause) && (\n <IconButton\n svg={PlayPauseIcon}\n svgSize={SvgContainerSize.Standard}\n className='bg-gray-200 rounded-circle cursor-pointer'\n onClick={props.togglePlayPause}\n ariaLabel={props.isPlaying ? getPhrase('pause') : getPhrase('play')}\n role='button'\n tooltip={props.isPlaying ? getPhrase('pause') : getPhrase('play')}\n tooltipTrigger={[ 'hover', 'focus' ]}\n />\n )}\n </div>\n );\n}\n\nexport function PartialPartnerProfileBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className='partial-banner partial-loading-background' />,\n portalContainerContext?.container\n );\n}\n\nexport type PartnerBannerHeaderType = 'static' | 'video';\n\nexport interface PartnerProfileBannerHeaderProps {\n heading: string;\n type?: 'partner-profile' | 'channel-topic';\n onClickSignUp?: (email: string) => void;\n isAuthenticated?: boolean;\n isStudent?: boolean;\n partnerBannerType?: PartnerBannerHeaderType;\n banner?: Banner;\n logo?: Logo;\n videoUrl?: string;\n imageCdnUrl?: string;\n logoBgColour?: string;\n actions?: ActionOptions[];\n blockColourClass?: string;\n websiteUrl?: string;\n log?: ContentPartnerEventLoggerFn;\n}\n\nconst VIDEO_BANNER_WIDTH = 1920;\nconst VIDEO_BANNER_RATIO = '1200:330';\n\nexport function PartnerProfileBannerHeader(props: PartnerProfileBannerHeaderProps): JSX.Element {\n const { heading, isAuthenticated, partnerBannerType = 'static', websiteUrl } = props;\n\n const isChannelTopic = props.type === 'channel-topic';\n\n const {\n videoRef,\n isPlaying,\n isFinished,\n loaded,\n togglePlayPause\n } = useVideoControls({\n addDelayOnLoad: 2500,\n log: props.log\n });\n\n // channel-topic banners never show the video banner or the sign-up CTA.\n const showVideoBanner = !isChannelTopic && partnerBannerType === 'video' && !!props.videoUrl;\n const isVideoVisible = loaded && !isFinished;\n\n const { containerProps, portalContainerContext, logoUrl } = useBannerHeader({\n heading,\n banner: props.banner,\n logo: props.logo,\n imageCdnUrl: props.imageCdnUrl,\n blockColourClass: props.blockColourClass,\n bannerClassName: classNames(\n showVideoBanner && 'banner-header-video position-relative',\n showVideoBanner && styles.videoBannerRadius\n ),\n bannerImageOptions: showVideoBanner ? {\n width: VIDEO_BANNER_WIDTH,\n ratio: VIDEO_BANNER_RATIO,\n resizeType: ResizeType.Cover\n } : null\n });\n\n const contentType = PartnerProfileBannerHeaderHelper.getBannerHeaderContentType({\n logoUrl,\n isAuthenticated,\n showVideoBanner,\n isChannelTopic\n });\n\n const showLogo = contentType === 'logo' || contentType === 'sign-up' || contentType === 'logo-with-name';\n const controls = isVideoVisible ?\n AllVideoBannerControlOptions :\n [ VideoBannerControlOption.PlayPause, VideoBannerControlOption.WebsiteLink ];\n \n return PortalHelper.renderInPortalIfExists(\n <header className={classNames(\n styles.header,\n showVideoBanner && 'px-0 px-xl-3 pt-xl-3 ',\n showLogo && styles.hasLogo\n )}>\n <div {...containerProps}>\n {showVideoBanner && (\n <VideoBannerContent\n videoUrl={props.videoUrl}\n videoRef={videoRef}\n className={classNames(styles.videoContent, isVideoVisible && styles.videoVisible)}\n // If loop is true then isFinished will never be true.\n loop={!props.banner}\n />\n )}\n <PartnerProfileBannerHeaderContent\n type={contentType}\n name={heading}\n logoUrl={logoUrl}\n bgColor={props.logoBgColour}\n onClickSignUp={props.onClickSignUp}\n />\n {showVideoBanner && (\n <VideoBannerControls\n isPlaying={isPlaying}\n togglePlayPause={togglePlayPause}\n controls={controls}\n websiteUrl={websiteUrl}\n isStudent={props.isStudent}\n log={props.log}\n />\n )}\n </div>\n </header>,\n portalContainerContext?.container\n );\n}\n","import React from 'react';\n\nimport {\n DefaultBannerHeader,\n DefaultBannerHeaderProps,\n PartialDefaultBannerHeader\n} from './default-banner-header/DefaultBannerHeader';\nimport {\n PartialPartnerProfileBannerHeader,\n PartnerProfileBannerHeader,\n PartnerProfileBannerHeaderProps\n} from './partner-profile-banner-header/PartnerProfileBannerHeader';\n\ntype InternalDefaultBannerHeaderProps = DefaultBannerHeaderProps & {\n type?: 'default'\n};\n\ntype InternalPartnerProfileBannerHeaderProps = PartnerProfileBannerHeaderProps & {\n type?: 'partner-profile'\n};\n\ntype InternalChannelTopicBannerHeaderProps = PartnerProfileBannerHeaderProps & {\n type?: 'channel-topic'\n};\n\ntype BannerHeaderProps =\n InternalDefaultBannerHeaderProps |\n InternalPartnerProfileBannerHeaderProps |\n InternalChannelTopicBannerHeaderProps;\n\ntype BannerType = BannerHeaderProps['type'];\ntype BannerTypeOptions = {\n Component: React.ComponentType<any>,\n PartialComponent: React.ComponentType<any>\n};\n\nconst bannerTypeMap: Record<BannerType, BannerTypeOptions> = {\n 'default': {\n Component: DefaultBannerHeader,\n PartialComponent: PartialDefaultBannerHeader\n },\n 'partner-profile': {\n Component: PartnerProfileBannerHeader,\n PartialComponent: PartialPartnerProfileBannerHeader\n },\n 'channel-topic': {\n Component: PartnerProfileBannerHeader,\n PartialComponent: PartialPartnerProfileBannerHeader\n }\n};\n\nexport function BannerHeader(props: BannerHeaderProps): JSX.Element {\n const { type = 'default' } = props;\n\n const Component = bannerTypeMap[type].Component;\n return <Component {...props} />;\n}\n\ninterface PartialBannerHeaderProps {\n type?: BannerType;\n}\n\nexport function PartialBannerHeader(props: PartialBannerHeaderProps): JSX.Element {\n const { type = 'default' } = props;\n\n const PartialComponent = bannerTypeMap[type].PartialComponent;\n return <PartialComponent {...props} />;\n}\n","import React from 'react';\n\nimport { Middleware, type MiddlewareFunctionSync } from 'libs/common/backbone/core';\n\nexport type UseTransformerFunc<T> = (options: T) => T;\n\nexport function useTransformer<T>(transformations?: MiddlewareFunctionSync<T>[]) {\n const middleware = React.useMemo(() => new Middleware<T>(), []);\n\n React.useEffect(() => {\n if (!transformations || !transformations.length)\n return;\n\n transformations.forEach(fn => middleware.useSync(fn));\n }, []);\n\n function push(fn: MiddlewareFunctionSync<T>): void {\n if (!middleware)\n return;\n\n middleware.useSync(fn);\n }\n\n function execute(options: T): T {\n if (!middleware)\n return;\n \n return middleware.goSync(options);\n }\n \n return {\n push,\n execute\n };\n}\n","import React from 'react';\n\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { handleHttpError } from 'libs/shared/errors/handlers/HttpErrorHandlers';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useInfiniteList } from 'libs/shared/hooks/UseInfiniteList';\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\nimport { useTransformer, UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { BaseWidget } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.useInfiniteWidgetFetch';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UseInfiniteWidgetFetchOptions<TItem, TWidget> {\n item: TItem;\n infiniteFetch: boolean;\n getRequest: (cursor?: string) => Flight.Request;\n getCursor: (widget: TWidget) => string;\n setIsEmpty?: (isEmpty: boolean) => void;\n isEmptyPredicate?: (items: TWidget[]) => boolean;\n \n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n}\n\nexport function useInfiniteWidgetFetch<\n TItem extends BaseWidget,\n TWidget extends BaseWidget\n>(options: UseInfiniteWidgetFetchOptions<TItem, TWidget>) {\n const fetch = Flight.useGetFetch();\n const alerts = useAlerts();\n const { ref: partialLoadingRef, inView } = useLazyLoad();\n const resultsTransformers = useTransformer<TWidget[]>(options.resultsTransformers ?? []);\n const widgetItemTransformers = useTransformer<TWidget>(options.widgetItemTransformers ?? []);\n \n function fetchNext(cursor?: string) {\n return fetch(options.getRequest(cursor));\n }\n\n function onError(pageNumber: number, httpStatus: HttpStatus): void {\n if (pageNumber === 1)\n return handleHttpError(httpStatus);\n\n alerts.error(getPhrase('error'));\n }\n \n function getItems(response: TWidget) {\n return [response];\n }\n \n const fetchResults = useInfiniteList<TWidget, TWidget>(\n inView && options.getRequest,\n inView && fetchNext,\n onError,\n getItems,\n options.infiniteFetch && options.getCursor\n );\n\n function transformResults(data: TWidget[]): TWidget[] {\n if (!data || !data.length)\n return;\n\n const results = resultsTransformers.execute(data);\n\n if (!options.widgetItemTransformers?.length)\n return results;\n\n const transformedResults = results.map(item => widgetItemTransformers.execute(item));\n\n return transformedResults;\n }\n\n /**\n * This is an array of widgets because technically we can have same widget type id\n * but different template id. This is the case the search series widget.\n */\n const items = transformResults(fetchResults.items);\n\n /**\n * Side effects below\n */\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted || !items)\n return;\n\n if (!options.onLoadWidgetsTriggers?.length || !items.length)\n return;\n\n options.onLoadWidgetsTriggers.forEach(onLoad => onLoad(items));\n }, [ fetchResults.hasFirstPageCompleted, items ]);\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted)\n return;\n\n if (!items) {\n options.setIsEmpty?.(true);\n return;\n }\n\n if (Array.isArray(items) && !items.length) {\n options.setIsEmpty?.(true);\n return;\n }\n\n if (!options.isEmptyPredicate)\n return;\n\n /**\n * For some reason our widget data structure is different for different dashboard targets.\n * Since it is inconsistent we can use the custom isEmptyPredicate check if the default\n * check above does not handle the use case.\n */\n options.setIsEmpty?.(options.isEmptyPredicate(items));\n }, [ fetchResults.hasFirstPageCompleted, options.isEmptyPredicate ]);\n\n const isEmpty = !items?.length;\n const showLoading = !fetchResults.hasFirstPageCompleted;\n const showInfiniteScrollFooter = options.infiniteFetch && (fetchResults.hasMore || fetchResults.isFetching);\n\n return {\n widgets: items,\n isEmpty,\n showLoading,\n showInfiniteScrollFooter,\n isFetching: fetchResults.isFetching,\n nextCursor: fetchResults.nextCursor,\n fetchNext,\n partialLoadingRef\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { InfiniteScrollFooter } from 'libs/shared/components/infinite-scroll-footer/InfiniteScrollFooter';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllWidgetTemplateProps } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { type HasLocalPermissionsFunc, type HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { type BaseObject, BaseWidget, CalendarEventContentType, type CurrentUser, CurriculumData, DashboardTargetType, type Presentation, type PresentationAudience, WidgetMetadata } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nimport { useInfiniteWidgetFetch } from './hooks/useInfiniteWidgetFetch';\n\ntype InferredWidgetTemplateProps = {\n appLinks: any,\n appLinkOptions?: any\n};\n\n/**\n * Props for InfiniteWidgetContainerView component\n *\n * @template TItem - The type of the widget item (extends BaseWidget)\n * @template TWidget - The type of individual widget content (extends BaseWidget)\n * @template TWidgetTemplateProps - The widget template props type for type-safe appLinks and appLinkOptions\n *\n * Use TWidgetTemplateProps to get type safety for specific dashboard targets:\n * @example\n * // For Search dashboard with type safety:\n * import { AllSearchWidgetTemplates } from './WidgetProps';\n *\n * <InfiniteWidgetContainerView<MyItem, MyWidget, AllSearchWidgetTemplates>\n * dashboardTarget={DashboardTargetType.Search}\n * appLinks={searchAppLinks} // Typed as AllSearchWidgetTemplates['appLinks']\n * appLinkOptions={searchAppLinkOptions} // Typed as AllSearchWidgetTemplates['appLinkOptions']\n * // ... other props\n * />\n */\ninterface InfiniteWidgetContainerViewProps<\n TItem,\n TWidget,\n TWidgetTemplateProps extends InferredWidgetTemplateProps = AllWidgetTemplateProps\n> {\n index: number;\n item: TItem;\n /**\n * If set to false will only fetch the first page\n */\n infiniteFetch: boolean;\n\n currentUser?: CurrentUser;\n audiences: PresentationAudience[];\n commonVideoProps: CommonVideoProps;\n dashboardTarget?: DashboardTargetType;\n availablePresentations?: Presentation[];\n presentation?: Presentation;\n\n analyticsData?: HashObject;\n imageCdnUrl?: string;\n imageUrls?: AllWidgetTemplateProps['imageUrls'];\n resourceThumbnailFallbackImageUrl?: string;\n lazyLoad?: boolean;\n\n headingElementRef?: React.MutableRefObject<Set<Element>>;\n hasTableOfContents?: boolean;\n isScrollToTargetWidget?: boolean;\n isBot?: boolean;\n isPreviewing?: boolean;\n isEditing?: boolean;\n curriculums?: CurriculumData;\n contentType?: CalendarEventContentType;\n\n /**\n * App links - type is determined by TWidgetTemplateProps generic parameter\n * Defaults to AllWidgetTemplateProps['appLinks'] if not specified\n */\n appLinks: TWidgetTemplateProps['appLinks'];\n\n /**\n * App link options - type is determined by TWidgetTemplateProps generic parameter\n * Defaults to AllWidgetTemplateProps['appLinkOptions'] if not specified\n */\n appLinkOptions?: TWidgetTemplateProps['appLinkOptions'];\n\n settingsHash?: SettingsHash;\n hasPermissions: HasPermissionsFunc;\n getName: (widget: TWidget) => string;\n getPartialLoadingPredicate?: () => boolean;\n hasLocalPermissions: HasLocalPermissionsFunc;\n getWidgetClassName?: (widget: TWidget) => string;\n getBadgeComponent?: (widget: TWidget) => JSX.Element;\n getSeeMoreAppLink?: (widget: TWidget) => Core.AppLink;\n getSelectedItems: (type: WidgetTypeId) => BaseObject[];\n getWidgetMetadata: (widget: TWidget) => Partial<WidgetMetadata>;\n getAnalyticsData?: (widget: TWidget, yIndex: number, xIndex: number) => HashObject;\n \n getCursor: (widget: TWidget) => string;\n getRequest: (cursor?: string) => Flight.Request;\n setIsEmpty?: (isEmpty: boolean) => void;\n getContent?: (widget: TWidget) => BaseObject[];\n\n /**\n * A predicate to determine if the widget is empty. \n * This is used to determine if the widget should be displayed as empty. \n * If not provided, the widget will be displayed as empty if the content is empty. \n * Only to be used if the widget data structure is inconsistent for different dashboard targets. \n */\n isEmptyPredicate?: (items: TWidget[]) => boolean;\n \n /**\n * Array of transformers to be applied to results before rendering\n */\n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n /**\n * Array of transformers to be applied to each widget item before rendering\n */\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n /**\n * Array of callbacks to be executed when widget is first loaded\n */\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n onClickSearchAllVideos?: () => void;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function InfiniteWidgetContainerView<\n TItem extends BaseWidget = BaseWidget,\n TWidget extends BaseWidget = BaseWidget,\n TWidgetTemplateProps extends InferredWidgetTemplateProps = AllWidgetTemplateProps\n>(props: InfiniteWidgetContainerViewProps<TItem, TWidget, TWidgetTemplateProps>): JSX.Element {\n const {\n isEmpty,\n widgets,\n partialLoadingRef,\n showLoading,\n fetchNext,\n isFetching,\n nextCursor,\n showInfiniteScrollFooter\n } = useInfiniteWidgetFetch({\n getRequest: props.getRequest,\n getCursor: props.getCursor,\n setIsEmpty: props.setIsEmpty,\n isEmptyPredicate: props.isEmptyPredicate,\n item: props.item,\n infiniteFetch: props.infiniteFetch,\n resultsTransformers: props.resultsTransformers,\n onLoadWidgetsTriggers: props.onLoadWidgetsTriggers,\n widgetItemTransformers: props.widgetItemTransformers\n });\n\n const template = WidgetTemplateConfig[props.item.templateId];\n const PartialTemplate = template.partialLoading;\n\n if (!template || !showLoading && isEmpty)\n return <></>;\n\n if (showLoading) {\n return (\n <div ref={partialLoadingRef} className='py-2'>\n <PartialTemplate\n name={props.item.name}\n description={props.item?.description}\n predicate={props?.getPartialLoadingPredicate}\n />\n </div>\n );\n }\n\n return (\n <>\n {widgets.map((widget, index) => {\n const isLastItem = index === widgets.length - 1;\n return (\n <React.Fragment key={`${widget.widgetId}-${widget.templateId}-${index}`}>\n <WidgetContainerView\n id={widget.id}\n widgetIndex={props.item.index}\n dashboardTarget={props.dashboardTarget}\n\n appLinks={props.appLinks}\n appLinkOptions={props.appLinkOptions}\n audiences={props.audiences}\n content={props.getContent?.(widget) ?? widget.content.data}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n currentUser={props.currentUser}\n commonVideoProps={props.commonVideoProps}\n availablePresentations={props.availablePresentations}\n presentation={props.presentation}\n\n analyticsData={props.analyticsData}\n imageCdnUrl={props.imageCdnUrl}\n imageUrls={props.imageUrls}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n lazyLoad={props.lazyLoad}\n\n name={props.getName(widget)}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n getSelectedItems={props.getSelectedItems}\n metadata={props.getWidgetMetadata(widget)}\n seeMoreLink={props.getSeeMoreAppLink?.(widget)}\n badgeComponent={props.getBadgeComponent?.(widget)}\n getAnalyticsData={\n props.getAnalyticsData && (xIndex => props.getAnalyticsData(widget, props.index, xIndex))\n }\n className={props.getWidgetClassName?.(widget)}\n\n headingElementRef={props.headingElementRef}\n hasTableOfContents={props.hasTableOfContents}\n isScrollToTargetWidget={props.isScrollToTargetWidget}\n isBot={props.isBot}\n isEditing={props.isEditing}\n curriculums={props.curriculums}\n contentType={props.contentType}\n\n settings={null}\n settingsHash={props.settingsHash}\n description={null}\n isPreviewing={props.isPreviewing ?? false}\n onClickRemoveItem={null}\n onClickSearchAllVideos={props.onClickSearchAllVideos}\n />\n {showInfiniteScrollFooter && isLastItem && (\n <InfiniteScrollFooter\n isFetching={isFetching}\n fetchNext={fetchNext}\n fetchOnScroll\n nextCursor={nextCursor}\n />\n )}\n </React.Fragment>\n );\n })}\n </>\n );\n}\n","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { CuratedWidget } from 'libs/shared/interfaces';\n\nexport function useEmptyWidgets(widgets: CuratedWidget[]) {\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n\n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n function isEmptyWidget(widgetId: string): boolean {\n return emptyWidgets[widgetId] === true;\n }\n\n function setEmptyWidget(widgetId: string, isEmpty: boolean): void {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n setEmptyWidgets(newEmptyState);\n }\n\n return {\n emptyWidgets,\n isEmptyWidget,\n setEmptyWidget,\n setEmptyWidgets\n };\n}\n","import React from 'react';\n\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\n\nexport function useExpandableTextButton() {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const [ showButton, setShowButton ] = React.useState(false);\n\n function showOrHideButton() {\n if (containerRef.current)\n setShowButton(containerRef.current.scrollHeight > containerRef.current.clientHeight);\n }\n\n // Show or hide the button when the containerRef is initially set\n React.useEffect(() => {\n showOrHideButton();\n }, [containerRef.current]);\n\n // Show or hide the button when the window is resized\n useResizeListener(() => {\n showOrHideButton();\n });\n\n return { containerRef, showButton };\n}\n",":local {\n .collapsed {\n overflow: hidden;\n max-height: calc(var(--lines) * 1lh);\n }\n\n .spacer {\n float: right;\n height: 100%;\n width: 0;\n }\n\n .moreButton {\n float: right;\n clear: right;\n }\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { useExpandableTextButton } from 'libs/shared/hooks/useExpandableTextButton';\n\nimport styles from './expandable-text-inline.module.scss';\n\ninterface ExpandableTextInlineProps {\n children: (props: { expanded: boolean }) => JSX.Element;\n lines?: number;\n}\n\nconst namespace = 'shared.expandableTextInline';\n\nexport function ExpandableTextInline(props: ExpandableTextInlineProps): JSX.Element {\n const { lines = 1 } = props;\n const [ expanded, setExpanded ] = React.useState(false);\n\n const { containerRef, showButton } = useExpandableTextButton();\n const TextComponent = props.children;\n\n return (\n <div\n ref={containerRef}\n style={{ '--lines': lines } as unknown as React.CSSProperties}\n className={classNames(!expanded && styles.collapsed)}\n >\n {!expanded && showButton && (\n <>\n <span className={styles.spacer} />\n <DivButton\n onClick={() => setExpanded(true)}\n className={classNames(styles.moreButton, 'text-dark hover-text-underline')}\n >\n <Text namespace={namespace} phrase='more' />\n </DivButton>\n </>\n )}\n <TextComponent expanded={expanded} />\n {(expanded) && (\n <DivButton\n onClick={() => setExpanded(false)}\n className='text-dark hover-text-underline text-underline'\n >\n <Text namespace={namespace} phrase='less' />\n </DivButton>\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\n\nimport { ContentPartnersHelper } from 'libs/shared/apps/content-partners/utils/ContentPartnersHelper';\nimport { ExpandableTextInline } from 'libs/shared/components/expandable-text-inline/ExpandableTextInline';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { LinkSvg } from 'libs/shared/images/svg/objects/LinkSvg';\nimport { PartnerProfile } from 'libs/shared/interfaces';\n\ninterface ChannelDashboardDescriptionProps {\n partnerProfile: PartnerProfile;\n}\n\nexport function ChannelDashboardDescription(props: ChannelDashboardDescriptionProps): JSX.Element {\n const websiteLink = ContentPartnersHelper.getPartnerLinkByType(\n props.partnerProfile?.links,\n 'website',\n ContentPartnersHelper.makeUTMs({ slug: props.partnerProfile._slug.value })\n );\n\n const displayWebsiteLink = UrlHelper.getHostname(websiteLink) ?? websiteLink;\n\n return (\n <div className='mt-3'>\n <ExpandableTextInline>\n {() => (\n <p className='mb-0'>\n {websiteLink && (\n <>\n <a\n href={websiteLink}\n target='_blank'\n rel='noopener noreferrer'\n className='position-relative d-inline-block ps-4 mb-2 me-2'\n >\n <SvgContainer svg={LinkSvg} className='svg-container position-absolute top-50 start-0 translate-middle-y' />\n <span className='ps-1'>{displayWebsiteLink}</span>\n </a>\n <span className='mb-2 me-2'>&bull;</span>\n </>\n )}\n {props.partnerProfile.description}\n </p>\n )}\n </ExpandableTextInline>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'contentPartners.contentPartnerDashboardComingSoon';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface ContentPartnerDashboardComingSoonProps {\n partnerName: string;\n comingSoonImageUrl: string;\n}\n\nexport function ContentPartnerDashboardComingSoon(props: ContentPartnerDashboardComingSoonProps): JSX.Element {\n return (\n <EmptyState>\n <EmptyState.Image\n src={props.comingSoonImageUrl}\n altText={getPhrase('description', { partnerName: props.partnerName })}\n />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='description' options={{ partnerName: props.partnerName }} />\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'contentPartners.contentPartnerDashboardContentRegion';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface ContentPartnerDashboardContentRegionProps {\n contentRegionImageUrl: string;\n contentRegionButtonLink: Core.AppLink;\n}\n\nexport function ContentPartnerDashboardContentRegion(props: ContentPartnerDashboardContentRegionProps): JSX.Element {\n return (\n <EmptyState>\n <EmptyState.Image src={props.contentRegionImageUrl} altText={getPhrase('imageAlt')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Cta text={getPhrase('cta')} appLink={props.contentRegionButtonLink} className='btn btn-dark' />\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'contentPartners.contentPartnerDashboardNoContent';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface ContentPartnerDashboardNoContentProps {\n noContentImageUrl: string;\n}\n\nexport function ContentPartnerDashboardNoContent(props: ContentPartnerDashboardNoContentProps): JSX.Element {\n return (\n <EmptyState>\n <EmptyState.Image\n src={props.noContentImageUrl}\n altText={getPhrase('description')}\n />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='description' />\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport {\n ContentPartnerDashboardComingSoon,\n ContentPartnerDashboardComingSoonProps\n} from '../content-partner-dashboard-coming-soon/ContentPartnerDashboardComingSoon';\nimport {\n ContentPartnerDashboardContentRegion,\n ContentPartnerDashboardContentRegionProps\n} from '../content-partner-dashboard-content-region/ContentPartnerDashboardContentRegion';\nimport {\n ContentPartnerDashboardNoContent,\n ContentPartnerDashboardNoContentProps\n} from '../content-partner-dashboard-no-content/ContentPartnerDashboardNoContent';\n\nexport type ContentPartnerEmptyStateType = 'coming-soon' | 'content-region' | 'no-content';\n\nconst ContentParterEmptyStateTypes: Record<ContentPartnerEmptyStateType, React.ComponentType<any>> = {\n 'coming-soon': ContentPartnerDashboardComingSoon,\n 'content-region': ContentPartnerDashboardContentRegion,\n 'no-content': ContentPartnerDashboardNoContent\n};\n\ntype EmptyStateType<TType extends ContentPartnerEmptyStateType, TProps> = TProps & {\n type: TType\n};\n\ntype ContentPartnerEmptyStateProps =\n EmptyStateType<'coming-soon', ContentPartnerDashboardComingSoonProps> |\n EmptyStateType<'content-region', ContentPartnerDashboardContentRegionProps> |\n EmptyStateType<'no-content', ContentPartnerDashboardNoContentProps>;\n\nexport function ContentPartnerEmptyState(props: ContentPartnerEmptyStateProps): JSX.Element {\n const Component = ContentParterEmptyStateTypes[props.type];\n\n return <Component {...props} />;\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ContentPartnersHelper } from 'libs/shared/apps/content-partners/utils/ContentPartnersHelper';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { InfiniteWidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/InfiniteWidgetContainerView';\nimport { AllPartnerProfileWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useEmptyWidgets } from 'libs/shared/hooks/useEmptyWidgets';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetQueryParams, CurrentUser, DashboardStatus, DashboardTargetType, PartnerProfile, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { ContentPartnerEventLoggerFn } from '../../utils/get-content-partner-event-logger/getContentPartnerEventLogger';\n\nimport { ChannelDashboardDescription } from './channel-dashboard-description/ChannelDashboardDescription';\nimport { ContentPartnerEmptyState, ContentPartnerEmptyStateType } from './empty-state/content-partner-empty-state/ContentPartnerEmptyState';\n\nconst InfiniteFetchWidgetIds: WidgetTypeId[] = [WidgetTypeId.ContentPartnerVideos];\n\nfunction shouldInfiniteFetch(widgets: CuratedWidget[], index: number): boolean {\n const currentWidget = widgets[index];\n\n if (!currentWidget) return false;\n \n return InfiniteFetchWidgetIds.includes(currentWidget.widgetId) && index === widgets.length - 1;\n}\n\nexport interface ContentPartnerDashboardProps {\n dashboard: CuratedDashboard;\n partnerProfile: PartnerProfile;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation?: Presentation,\n cursor?: string\n ) => Flight.Request;\n commonVideoProps: CommonVideoProps;\n getBannerActions?: () => ActionOptions[];\n breadcrumbs?: Breadcrumb[];\n isReadonly?: boolean;\n widgetAppLinks?: AllPartnerProfileWidgetTemplates['appLinks'];\n scrollToWidgetId?: string;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n settings?: AllPartnerProfileWidgetTemplates['settings'];\n audiences?: PresentationAudience[];\n currentUser?: CurrentUser;\n emptyImageUrl?: string;\n lazyLoad?: boolean;\n isBot?: boolean;\n isComingSoon?: boolean;\n isPreviewing?: boolean;\n isAuthenticated?: boolean;\n isInContentRegion: boolean;\n onClickSignUp: (email: string) => void;\n onClickSearchAllVideos?: () => void;\n getSeeMoreAppLink?: (widget: CuratedWidget) => Core.AppLink;\n log?: ContentPartnerEventLoggerFn;\n}\n\nexport function ContentPartnerDashboard(props: ContentPartnerDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { emptyWidgets, setEmptyWidget } = useEmptyWidgets(widgets);\n\n function getWidgetContentRequest(\n id: string,\n widgetTypeId: WidgetTypeId,\n template: WidgetTemplate,\n cursor?: string\n ): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template, undefined, cursor);\n }\n\n function getEmptyStateType(): ContentPartnerEmptyStateType | false {\n if (!props.isInContentRegion)\n return 'content-region';\n \n if (props.isComingSoon)\n return 'coming-soon';\n \n if (props.dashboard.status === DashboardStatus.Archived && !props.isReadonly)\n return 'coming-soon';\n \n if (props.dashboard.status === DashboardStatus.Draft && !props.isPreviewing)\n return false;\n\n if (!widgets?.length)\n return 'no-content';\n \n const emptyValues = Object.values(emptyWidgets);\n \n if (emptyValues.length > 0 && emptyValues.every(state => !!state))\n return 'no-content';\n\n return false;\n }\n\n const bannerInfo = ContentPartnersHelper.getPartnerBannerInfo(props.partnerProfile);\n\n const emptyState = getEmptyStateType();\n const showExpandableDescription = (!emptyState || emptyState === 'content-region') && props.partnerProfile.description;\n\n return (\n <>\n {!!widgets.length &&\n <>\n <BannerHeader\n type='partner-profile'\n partnerBannerType={ContentPartnersHelper.getPartnerBannerType(props.partnerProfile)}\n heading={bannerInfo.heading}\n blockColourClass={bannerInfo.blockColourClass}\n logo={bannerInfo.logo}\n logoBgColour={bannerInfo.logoBgColour}\n banner={bannerInfo.banner}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n actions={props.getBannerActions?.()}\n onClickSignUp={props.onClickSignUp}\n isAuthenticated={props.isAuthenticated}\n videoUrl={props.partnerProfile._videobanner?.value?.url}\n websiteUrl={ContentPartnersHelper.getPartnerLinkByType(\n props.partnerProfile?.links,\n 'website',\n ContentPartnersHelper.makeUTMs({ slug: props.partnerProfile._slug.value })\n )}\n isStudent={props.hasPermissions(PermissionName.StudentExperience)}\n log={props.log}\n />\n \n <div className='py-3 mb-3 border-bottom'>\n <Breadcrumbs breadcrumbs={props.breadcrumbs} />\n {showExpandableDescription && (\n <ChannelDashboardDescription partnerProfile={props.partnerProfile} />\n )}\n </div>\n\n <div className='mt-3'>\n {!emptyState && widgets.map((widget, idx) => (\n <InfiniteWidgetContainerView<CuratedWidget, CuratedWidget, AllPartnerProfileWidgetTemplates>\n dashboardTarget={DashboardTargetType.PartnerProfile}\n key={widget.id}\n index={idx}\n item={widget}\n infiniteFetch={shouldInfiniteFetch(widgets, idx)}\n getName={widget => widget.name}\n getWidgetMetadata={w => w.metadata}\n appLinks={props.widgetAppLinks}\n hasPermissions={props.hasPermissions}\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n setIsEmpty={isEmpty => setEmptyWidget(widget.id, isEmpty)}\n getCursor={w => w.cursor}\n getRequest={cursor => getWidgetContentRequest(widget.id, widget.widgetId, widget.templateId, cursor)}\n hasLocalPermissions={props.hasLocalPermissions}\n settingsHash={props.settings}\n getContent={w => w.content}\n resultsTransformers={WidgetHelper.getWidgetResultsTransformers()}\n onClickSearchAllVideos={props.onClickSearchAllVideos}\n getSeeMoreAppLink={props.getSeeMoreAppLink}\n isEmptyPredicate={items => (\n Array.isArray(items) && Array.isArray(items[0]?.content) && !items[0]?.content?.length\n )}\n\n getSelectedItems={null}\n appLinkOptions={null}\n />\n ))}\n </div>\n </>\n }\n\n {emptyState && <ContentPartnerEmptyState\n type={emptyState}\n // Coming soon empty state props\n partnerName={props.partnerProfile.name}\n comingSoonImageUrl={props.emptyImageUrl}\n // Content region empty state props\n contentRegionImageUrl={props.emptyImageUrl}\n contentRegionButtonLink={props.widgetAppLinks?.partnerHome?.()}\n // No content empty state props\n noContentImageUrl={props.emptyImageUrl}\n />}\n </>\n );\n}\n","@import '~styles/utils/include-media';\n:local{\n .pillTab {\n @include media('<=md') {\n li {\n min-width: 5rem;\n }\n }\n\n }\n}","import React from 'react';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { DashboardUserType } from 'libs/shared/interfaces';\n\nimport styles from './discover-header.module.scss';\n\nconst namespace = 'discover.header';\n\nexport interface DiscoverHeaderAppLinks {\n forYou: Core.AppLink;\n whatsNew: Core.AppLink;\n calendar: Core.AppLink;\n}\n\ninterface DiscoverHeaderProps {\n type: DashboardUserType;\n hasStudentExperience?: boolean;\n appLinks?: DiscoverHeaderAppLinks;\n showCalendar: boolean;\n active: keyof DiscoverHeaderAppLinks;\n isUpselling?: boolean;\n}\n\nexport function DiscoverHeader(props: DiscoverHeaderProps): JSX.Element {\n if (!props.type)\n return <></>;\n\n if (props.type === DashboardUserType.Learner || props.hasStudentExperience) {\n return (\n <div className='py-3'>\n <h1 className='h2 mb-0'>\n <Text namespace={namespace} phrase='heading' />\n </h1>\n </div>\n );\n }\n\n if (props.isUpselling)\n return <></>;\n\n const tabs = [{\n name: LanguageService.getPhrase(namespace, 'forYou'),\n appLink: props.appLinks?.forYou,\n active: props.active === 'forYou',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'forYou'),\n url: AppLinkHelper.getHref(props.appLinks?.forYou)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n }, {\n name: LanguageService.getPhrase(namespace, 'whatsNew'),\n appLink: props.appLinks?.whatsNew,\n active: props.active === 'whatsNew',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'whatsNew'),\n url: AppLinkHelper.getHref(props.appLinks?.whatsNew)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n },\n {\n name: LanguageService.getPhrase(namespace, 'calendar'),\n appLink: props.appLinks?.calendar,\n active: props.active === 'calendar',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'calendar'),\n url: AppLinkHelper.getHref(props.appLinks?.calendar)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n hide: !props.showCalendar\n }];\n\n return (\n <div className='py-3 text-center mx-n3'>\n <PillTabSelector\n tabs={tabs}\n className={styles.pillTab}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { VideoWidgetItemV2 } from 'libs/shared/components/widgets/items/video-widget-item/v2/VideoWidgetItemV2';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { PlaylistRequests } from 'libs/shared/flight-requests/PlaylistRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { CurrentUser, Following, PresentationAudience, Video, VideoTypes } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nconst namespace = 'discover.tutorials';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface TutorialVideosContext {\n playlistId: string;\n videos?: VideoTypes[];\n shouldShowPanel: boolean;\n readyToShowPanel: boolean;\n shouldShowProductTip: boolean;\n dismissPanel?: () => void;\n appLink?: Core.AppLink;\n getVideoAppLink?: (child: Video) => Core.AppLink;\n}\n\ninterface TutorialVideoWidgetProps {\n commonVideoProps: CommonVideoProps;\n audiences: PresentationAudience[];\n context: TutorialVideosContext;\n}\n\nexport function TutorialVideoWidget(props: TutorialVideoWidgetProps) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n \n const following = Flight.useBasicFetch<Following>(\n currentUser.data?.id &&\n PlaylistRequests.getIsFollowingPlaylist(props.context.playlistId, currentUser.data?.id)\n );\n\n const [ isFollowing, setIsFollowing ] = React.useState(null);\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n const alerts = useAlerts();\n const fetchAsync = Flight.useGetFetchAsync();\n\n React.useEffect(() => {\n if (following.hasCompleted) {\n setIsFollowing(following.data?.isFollowing);\n }\n }, [following.data?.isFollowing]);\n\n const follow = async (shouldFollow: boolean) => {\n setShowSpinner(true);\n\n const req = shouldFollow ?\n PlaylistRequests.followPlaylist :\n PlaylistRequests.unfollowPlaylist;\n\n const error = () => {\n alerts.error(getPhrase(shouldFollow ? 'followError' : 'unfollowError'));\n setShowSpinner(false);\n };\n\n const success = () => {\n alerts.success(getPhrase(shouldFollow ? 'followSuccess' : 'unfollowSuccess'));\n setIsFollowing(shouldFollow);\n setShowSpinner(false);\n };\n\n await fetchAsync(req(props.context.playlistId, currentUser.data?.id, success, error));\n };\n \n return (\n <FixedWidget\n name={getPhrase('heading')}\n contents={WidgetContents.Videos}\n appLink={props.context.appLink}\n getChildAppLink={props.context.getVideoAppLink}\n collection={props.context.videos}\n childComponent={VideoWidgetItemV2}\n extraChildComponentProps={{\n commonVideoProps: props.commonVideoProps,\n presentationAudiences: props.audiences\n }}\n showSeeMoreLink={false}\n onClose={props.context.dismissPanel}\n onFollow={follow}\n isFollowing={isFollowing}\n showFollowSpinner={showSpinner}\n prefetched\n />\n );\n}\n","@import '~styles/utils/include-media';\n\n:local {\n .container {\n background-size: cover;\n }\n\n .eventLogo {\n width: 2.0625rem; //32px + 1px border\n height: 2.0625rem;\n }\n\n .cvLogoContainer {\n width: 2.0625rem;\n height: 2.0625rem;\n }\n\n .cvLogo {\n width: 0.625rem;\n // ClickView logo looks better when positioned slightly further to the right\n left: 53%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n .countdownGrid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: map-get($spacers, 1);\n\n @include media('<=md') {\n margin-top: map-get($spacers, 2);\n }\n }\n\n .timeBox {\n width: 4.3125rem;\n height: 4.3125rem;\n border: 0.125rem solid $light-blue;\n }\n\n .timeLabel {\n font-size: 0.75rem; //12px\n }\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink as AppLinkComponent } from 'libs/shared/components/app-link/AppLink';\nimport { ClickViewPlayLogo } from 'libs/shared/components/svgs/clickview-logo/ClickViewLogo';\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport styles from './countdown.module.scss';\n\nconst timeUnitNamespace = 'shared.countdown';\n\ninterface TimeBoxProps {\n value: number;\n label: string;\n shouldFormat: boolean;\n}\n\nfunction formatNumber(num: number) {\n return num.toString().padStart(2, '0');\n}\n\nfunction TimeBox(props: TimeBoxProps) {\n return (\n <div className={`bg-white d-flex rounded-3 flex-column align-items-center justify-content-center p-1 ${styles.timeBox}`}>\n <div className='fs-5 h6 mb-0 flex-grow-1 align-content-center'>\n {props.shouldFormat ? formatNumber(props.value) : props.value}\n </div>\n <div className={styles.timeLabel}>{props.label}</div>\n </div>\n );\n}\n\nexport interface CountdownWidgetProps {\n targetDate: Date;\n endDate: Date;\n imageUrls: CountdownImageUrls;\n langNamespace: string;\n appLink?: AppLink;\n onCtaClick?: () => void;\n /** When true, the event has ended but is still shown (due to showDaysAfter). */\n hasEnded?: boolean;\n}\n\nexport function CountdownWidget(props: CountdownWidgetProps): JSX.Element | null {\n const [ timeLeft, setTimeLeft ] = React.useState({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0\n });\n const [ isEventEnded, setIsEventEnded ] = React.useState(false);\n const shouldShowLogos = props.imageUrls.logo;\n\n React.useEffect(() => {\n let timer: number = 0;\n\n const calculateTimeLeft = () => {\n const now = new Date().getTime();\n const targetTime = props.targetDate.getTime();\n const endTime = props.endDate.getTime();\n\n if (now >= endTime) {\n setIsEventEnded(true);\n clearInterval(timer);\n return;\n }\n\n const difference = targetTime - now;\n\n if (difference > 0) {\n setTimeLeft({\n days: Math.floor(difference / (1000 * 60 * 60 * 24)),\n hours: Math.floor((difference / (1000 * 60 * 60)) % 24),\n minutes: Math.floor((difference / 1000 / 60) % 60),\n seconds: Math.floor((difference / 1000) % 60)\n });\n } else {\n setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });\n clearInterval(timer);\n }\n };\n\n calculateTimeLeft();\n timer = window.setInterval(calculateTimeLeft, 1000);\n\n return () => clearInterval(timer);\n }, [ props.targetDate, props.endDate ]);\n\n if (isEventEnded && !props.hasEnded) {\n return null;\n }\n\n const timeUnits = [\n { value: timeLeft.days, label: LanguageService.getPhrase(timeUnitNamespace, 'days'), format: false },\n { value: timeLeft.hours, label: LanguageService.getPhrase(timeUnitNamespace, 'hours'), format: true },\n { value: timeLeft.minutes, label: LanguageService.getPhrase(timeUnitNamespace, 'minutes'), format: true },\n { value: timeLeft.seconds, label: LanguageService.getPhrase(timeUnitNamespace, 'seconds'), format: true }\n ];\n\n const isCountdownFinished = timeLeft.days === 0\n && timeLeft.hours === 0\n && timeLeft.minutes === 0\n && timeLeft.seconds === 0;\n\n return (\n <div\n className={`${styles.container} position-relative d-flex flex-md-row justify-content-md-between flex-column justify-content-center align-items-center p-3 mb-4 rounded`}\n style={{\n backgroundImage: `url('${props.imageUrls.background}')`\n }}\n >\n <div className='d-flex flex-column gap-2 align-items-md-start align-items-center w-md-auto w-100'>\n <div className='d-flex flex-md-row align-items-center flex-column gap-2'>\n {shouldShowLogos && (\n <ul className='list-unstyled d-flex mb-0'>\n <li className={`bg-white rounded-circle z-1 ${styles.eventLogo} border`}>\n <img src={props.imageUrls.logo} className='rounded-circle img-fluid' />\n </li>\n <li className={`bg-white rounded-circle position-relative ms-n1 ${styles.cvLogoContainer} border`}>\n <div className={`position-absolute d-flex align-items-center justify-content-center ${styles.cvLogo}`}>\n <ClickViewPlayLogo />\n </div>\n </li>\n </ul>\n )}\n <h2 className='h4 text-white text-shadow mb-0 lh-1 my-3 my-md-0'>\n {props.hasEnded ?\n LanguageService.getPhrase(props.langNamespace, 'titleAfter') :\n isCountdownFinished ?\n LanguageService.getPhrase(props.langNamespace, 'titleStarted') :\n LanguageService.getPhrase(props.langNamespace, 'title')}\n </h2>\n </div>\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit d-none d-md-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'cta')}\n </AppLinkComponent>\n }\n </div>\n\n {!isCountdownFinished &&\n <div className={styles.countdownGrid}>\n {timeUnits.map(unit => <TimeBox key={unit.label} {...unit} shouldFormat={unit.format} />)}\n </div>\n }\n\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit mt-3 d-md-none d-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'ctaMobile')}\n </AppLinkComponent>\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\n\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport { CountdownWidget } from './CountdownWidget';\n\ninterface ImageUrlMap {\n [key: string]: ImageUrlMap | string;\n}\n\nexport interface CountdownExternalContext {\n // Map of image URL constants from the consuming project\n imageUrls: ImageUrlMap;\n getAppLink: (presentationId: string, eventTopicKey: string) => AppLink | null;\n}\n\ninterface ResolvedEventData {\n imageUrls: CountdownImageUrls | null;\n appLink?: AppLink | null;\n}\n\nexport interface CountdownEventConfig {\n key: string;\n // countdown will count towards this date\n targetDate: Date;\n // event is hidden after this date\n endDate: Date;\n langNamespace: string;\n allowedPresentationIds: string[];\n // key used to look up event topics in HardCoded (e.g. 'OlympicsTopics', 'CommonwealthGameTopics')\n eventTopicKey: string;\n getEventConfig: (presentationId: string, context: CountdownExternalContext) => ResolvedEventData;\n /** \n * Number of days before targetDate to start showing the countdown.\n * If not provided, the countdown is shown immediately (as long as now < endDate).\n * Make sure to set up phrase 'titleStarted' for your event.\n */\n showDaysBefore?: number;\n /**\n * Number of days after endDate to keep showing the countdown.\n * If not provided, the countdown is hidden immediately after endDate.\n * Make sure to set up phrase 'tittleAfter' for your event.\n */\n showDaysAfter?: number;\n}\n\ninterface CountdownContainerProps {\n presentationId: string;\n // List of countdown event configs, ordered by priority\n events: CountdownEventConfig[];\n // External context passed from the consuming component\n context: CountdownExternalContext;\n}\n\nfunction getActiveEvent(\n events: CountdownEventConfig[],\n presentationId: string\n): CountdownEventConfig | undefined {\n const now = new Date().getTime();\n\n return events.find(event => {\n if (!event.allowedPresentationIds.includes(presentationId)) {\n return false;\n }\n\n const effectiveEndDate = event.showDaysAfter !== undefined ?\n event.endDate.getTime() + event.showDaysAfter * 24 * 60 * 60 * 1000 :\n event.endDate.getTime();\n\n if (now >= effectiveEndDate) {\n return false;\n }\n\n if (event.showDaysBefore !== undefined) {\n const showFromDate = new Date(event.targetDate.getTime() - event.showDaysBefore * 24 * 60 * 60 * 1000);\n if (now < showFromDate.getTime()) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nexport function CountdownContainer(props: CountdownContainerProps): JSX.Element | null {\n const activeEvent = getActiveEvent(props.events, props.presentationId);\n\n if (!activeEvent) {\n return null;\n }\n\n const config = activeEvent.getEventConfig(props.presentationId, props.context);\n\n if (!config.imageUrls) {\n return null;\n }\n\n const hasEnded = new Date().getTime() >= activeEvent.endDate.getTime();\n\n return (\n <CountdownWidget\n key={activeEvent.key}\n targetDate={activeEvent.targetDate}\n endDate={activeEvent.endDate}\n imageUrls={config.imageUrls}\n langNamespace={activeEvent.langNamespace}\n appLink={config.appLink}\n hasEnded={hasEnded}\n />\n );\n}\n","import { HardCoded } from 'libs/shared/constants/HardCoded';\n\nimport { CountdownEventConfig } from '../CountdownContainer';\n\nconst COMMONWEALTH_GAME_START_DATE_UTC = new Date('2026-07-23T00:00:00Z');\nconst COMMONWEALTH_GAME_END_DATE_UTC = new Date('2026-08-02T23:59:59Z');\n\nconst COMMONWEALTH_GAME_PRESENTATION_IDS = [\n HardCoded.PresentationIds.SCT_PRIMARY,\n HardCoded.PresentationIds.SCT_SECONDARY,\n HardCoded.PresentationIds.ENG_PRIMARY,\n HardCoded.PresentationIds.ENG_SECONDARY,\n HardCoded.PresentationIds.AU_PRIMARY,\n HardCoded.PresentationIds.AU_SECONDARY\n].map(id => id.toString());\n\nconst PRESENTATION_TO_IMAGE_KEY: Record<string, string> = {\n [HardCoded.PresentationIds.SCT_PRIMARY]: 'SCT_PRIMARY',\n [HardCoded.PresentationIds.SCT_SECONDARY]: 'SCT_SECONDARY',\n [HardCoded.PresentationIds.ENG_PRIMARY]: 'ENG_PRIMARY',\n [HardCoded.PresentationIds.ENG_SECONDARY]: 'ENG_SECONDARY',\n [HardCoded.PresentationIds.AU_PRIMARY]: 'AU_PRIMARY',\n [HardCoded.PresentationIds.AU_SECONDARY]: 'AU_SECONDARY'\n};\n\nexport const commonwealthGameCountdownEvent: CountdownEventConfig = {\n key: 'commonwealth-games-2026',\n targetDate: COMMONWEALTH_GAME_START_DATE_UTC,\n endDate: COMMONWEALTH_GAME_END_DATE_UTC,\n langNamespace: 'shared.commonwealthGameCountdown',\n allowedPresentationIds: COMMONWEALTH_GAME_PRESENTATION_IDS,\n eventTopicKey: 'CommonwealthGameTopics',\n // we want to show the event for 30 days before the start\n showDaysBefore: 30,\n // we want to show the event for 7 days after the end day\n showDaysAfter: 7,\n\n getEventConfig: (presentationId, context) => {\n const images = context.imageUrls.CommonwealthGamesCountdown as Record<string, string> | undefined;\n\n if (!images) {\n return { imageUrls: null };\n }\n\n const imageKey = PRESENTATION_TO_IMAGE_KEY[presentationId];\n const background = imageKey ? images[imageKey] as string : null;\n\n if (!background) {\n return { imageUrls: null };\n }\n\n const appLink = context.getAppLink(presentationId, 'CommonwealthGameTopics');\n\n return {\n // we don't show logos for this event\n imageUrls: { background },\n appLink\n };\n }\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.discoverDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface DiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function DiscoverDashboardEmptyState(props: DiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { DiscoverHeader, DiscoverHeaderAppLinks } from 'libs/shared/apps/discover/components/header/DiscoverHeader';\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { CountdownContainer, CountdownExternalContext } from 'libs/shared/components/widgets/countdown/CountdownContainer';\nimport { commonwealthGameCountdownEvent } from 'libs/shared/components/widgets/countdown/events/commonwealth-game';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience, WidgetPreference } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { DiscoverDashboardEmptyState } from './empty-state/DiscoverDashboardEmptyState';\n\nexport interface DiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation: Presentation\n ) => Flight.Request;\n audiences: PresentationAudience[];\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: DiscoverHeaderAppLinks;\n scrollToWidgetId?: string;\n updatePreferences?: (\n widgetId: string,\n widgetTypeId: WidgetTypeId,\n oldPreferences: WidgetPreference[],\n newPreferences: WidgetPreference[]\n ) => Promise<void>;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n removeFromVideoHistory: (videoId: string, videoName: string, widgetId: string, widgetTypeId: WidgetTypeId) => void;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n showCalendar: boolean;\n settings: SettingsHash;\n availablePresentations: Presentation[];\n isTertiaryCustomerWithoutExchange: boolean;\n commonVideoProps: CommonVideoProps;\n countdownContext?: CountdownExternalContext;\n tutorialVideosContext?: TutorialVideosContext;\n contentType?: CalendarEventContentType;\n isUpselling?: boolean;\n reminderComponent?: JSX.Element;\n}\n\nexport function DiscoverDashboard(props: DiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template, props.presentation);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <DiscoverHeader\n type={props.dashboard?.userType}\n appLinks={props.headerAppLinks}\n hasStudentExperience={props.hasPermissions(PermissionName.StudentExperience)}\n showCalendar={props.showCalendar}\n active='forYou'\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {props.countdownContext && props.presentation?.id && (\n <CountdownContainer\n presentationId={props.presentation.id.toString()}\n events={[commonwealthGameCountdownEvent]}\n context={props.countdownContext}\n />\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n preferences={widget.preferences}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n onSubmitFeedback={props.onSubmitFeedback}\n updatePreferences={props.updatePreferences}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n settings={{\n hasTopicDirectories: props.settings?.hasTopicDirectories\n }}\n availablePresentations={props.availablePresentations}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n settingsHash={props.settings}\n contentType={props.contentType}\n isUpselling={props.isUpselling}\n\n // TODO: Ideally we don't have to do this\n classification={undefined}\n hasTableOfContents={false}\n limitTotalItems={false}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n seeMoreLink={undefined}\n onClickRemoveItem={props.removeFromVideoHistory}\n badgeComponent={null}\n reminderComponent={props.reminderComponent}\n />\n );\n })}\n\n {showEmptyState && (\n <DiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'moviesAndTv.companyDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CompanyDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function CompanyDashboardEmptyState(props: CompanyDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { CompanyDashboardEmptyState } from 'libs/shared/apps/movies-and-tv/components/company-dashboard/empty-state/CompanyDashboardEmptyState';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader, PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllCompanyWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { Company, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nexport interface CompanyDashboardProps {\n dashboard: CuratedDashboard;\n company: Company;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n widgetAppLinks?: AllCompanyWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n getBreadcrumbs?: () => Breadcrumb[];\n getBannerActions?: () => ActionOptions[];\n commonVideoProps: CommonVideoProps;\n\n settings?: AllCompanyWidgetTemplates['settings'];\n}\n\nexport function CompanyDashboard(props: CompanyDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n {!!widgets.length &&\n <>\n {props.company ?\n (\n <BannerHeader\n heading={props.company.name}\n banner={props.company.banner}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n blockColourClass={getBgColorClass(props.company.name, BG_COLOUR_CLASS_NAMES)}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n />\n ) : <PartialBannerHeader />\n }\n\n <div className='py-3 mb-3 border-bottom'>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n </div>\n\n <div className='mt-3'>\n {widgets.map(widget => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Company}\n dashboardTarget={DashboardTargetType.Company}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n settings={props.settings}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n\n // TODO: Ideally we don't have to do this\n classification={null}\n contentType={null}\n hasTableOfContents={false}\n seeMoreLink={null}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n </div>\n </>\n }\n\n {showEmptyState && (\n <CompanyDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n",":local {\n .link {\n background-size: cover;\n background-position: 50% 50%;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UseProductsResponse } from 'libs/shared/hooks/UseProducts';\nimport { NewWindowSvg } from 'libs/shared/images/svg/actions/NewWindowSvg';\nimport { ExchangeTvProductOption } from 'libs/shared/interfaces/ExchangeTvProductOption';\n\nimport styles from './exchange-and-tv-links.module.scss';\n\nconst namespace = 'moviesAndTV.exchangeAndTvLinks';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface LinkProps {\n backgroundImage: string;\n backgroundColor: string;\n title: string;\n cta: string;\n href: string;\n}\n\nfunction Link(props: LinkProps): JSX.Element {\n function onClick(): void {\n AnalyticsHelper.logUserAction({ href: props.href }, {\n actionType: UserAction.Click,\n entity: EntityType.Link,\n location: LocationContext.ExchangeLinksWidget\n });\n }\n\n const style: React.CSSProperties = {\n backgroundColor: props.backgroundColor\n };\n\n if (props.backgroundImage)\n style.backgroundImage = `url(${props.backgroundImage})`;\n\n return (\n <div\n className={`d-flex justify-content-between align-items-center text-white p-3 mb-3 rounded-3 ${styles.link}`}\n style={style}\n >\n <a className='h6 text-shadow mb-0' href={props.href} target='_blank' onClick={onClick}>{props.title}</a>\n <IconButton\n href={props.href}\n svg={NewWindowSvg}\n openInNewTab\n className='btn btn-outline-dark d-lg-block d-none'\n onClick={onClick}\n >\n {props.cta}\n </IconButton>\n </div>\n );\n}\n\ninterface ExchangeAndTvLinksProps {\n isPrimary: boolean;\n exchangeTvProductOption: ExchangeTvProductOption;\n products: UseProductsResponse;\n}\n\nexport function ExchangeAndTvLinks(props: ExchangeAndTvLinksProps): JSX.Element {\n const shouldShow = (\n !props.products.isLoadingProducts &&\n props.products.hasProduct(ProductId.Exchange) &&\n props.exchangeTvProductOption === 'exchange_and_tv'\n );\n\n if (!shouldShow)\n return <></>;\n\n const exchangeUrl = props.products.products.data.find(p => p.id === ProductId.Exchange).url;\n\n return (\n <div>\n <div className='curated-widget-header'>\n <h2 className='h4 curated-widget-heading'>\n <Text namespace={namespace} phrase='title' />\n </h2>\n </div>\n <div className='row'>\n <div className='col-md-6 col-12'>\n <Link\n title={getPhrase('exchangeText')}\n cta={getPhrase('exchangeCta')}\n backgroundColor='#7A76EB'\n backgroundImage={props.isPrimary ? '' : 'https://img.clickviewapp.com/v2/thumbnails/7mqa32'}\n href={exchangeUrl + '/exchange'}\n />\n </div>\n <div className='col-md-6 col-12'>\n <Link\n title={getPhrase('tvText')}\n cta={getPhrase('tvCta')}\n backgroundColor='#40BCC3'\n backgroundImage={props.isPrimary ? '' : 'https://img.clickviewapp.com/v2/thumbnails/Eo3L1k'}\n href={exchangeUrl + '/tv'}\n />\n </div>\n </div>\n </div>\n );\n}\n","import { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/flight';\n\nimport { BootstrapKeys } from 'libs/shared/constants/BootstrapKeys';\nimport { Product } from 'libs/shared/interfaces';\n\nexport const ProductRequests = {\n userProducts(\n success?: (data: Product[]) => void,\n error?: (xhr: Xhr) => void\n ): Flight.Request {\n return {\n url: '{gateway}/v1/users/me/products',\n key: 'user:products',\n normalizeOptions: {\n namespace: 'product'\n },\n success,\n error,\n bootstrapName: BootstrapKeys.PRODUCTS\n };\n }\n};\n","import { Flight } from 'libs/common/flight';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ProductRequests } from 'libs/shared/flight-requests/ProductRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { CurrentUser, Product } from 'libs/shared/interfaces';\n\nexport type HasProductFunc = (productId: ProductId) => boolean;\n\nexport interface UseProductsResponse {\n hasProduct: (product: ProductId) => boolean;\n products: Flight.Response<Product[]>;\n isLoadingProducts: boolean;\n}\n\nexport const useProducts = (): UseProductsResponse => {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const products = Flight.useBasicFetch<Product[]>(currentUser.data?.isAuthenticated && ProductRequests.userProducts());\n const isLoadingProducts = !products.hasCompleted;\n\n const hasProduct = (productId: ProductId) => {\n if (isLoadingProducts || products.hasError)\n return false;\n\n if (!products.data?.length)\n return false;\n\n return products.data.some(product => product.id === productId);\n };\n\n return {\n hasProduct,\n products,\n isLoadingProducts\n };\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'moviesAndTv.dashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface MoviesAndTvDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function MoviesAndTvDashboardEmptyState(props: MoviesAndTvDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n",":local {\n .icon {\n width: 2.875rem;\n height: 3.0625rem;\n background-size: cover;\n }\n .title {\n margin-top: 1rem;\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ExchangeAndTvLinks } from 'libs/shared/apps/movies-and-tv/components/exchange-and-tv-links/ExchangeAndTvLinks';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllMoviesAndTvWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationLearningLevel } from 'libs/shared/enums/PresentationLearningLevel';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { useProducts, UseProductsResponse } from 'libs/shared/hooks/UseProducts';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { InfoSvg } from 'libs/shared/images/svg/status/InfoSvg';\nimport { CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { MoviesAndTvDashboardEmptyState } from './empty-state/MoviesAndTvDashboardEmptyState';\n\nimport styles from './movies-and-tv-dashboard.module.scss';\n\nconst namespace = 'moviesAndTv.dashboard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface MoviesAndDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n moviesAndTvIconUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllMoviesAndTvWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n showPreviewingTooltip?: boolean;\n settings?: SettingsHash;\n products?: UseProductsResponse;\n commonVideoProps: CommonVideoProps;\n}\n\nexport function MoviesAndTvDashboard(props: MoviesAndDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { hasProduct } = useProducts();\n\n // todo replace with backend filtering widgets by permissions and products\n const hasExchange = props.hasPermissions(PermissionName.Exchange) && hasProduct(ProductId.Exchange);\n const filteredWidgets = props.isReadonly ?\n // in Curator every widget is visible\n widgets :\n widgets.filter(w =>\n (w.templateId !== WidgetTemplate.HeroBannerSmall && w.widgetId !== WidgetTypeId.Blurb)\n || hasExchange);\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !filteredWidgets?.length;\n\n return (\n <div className='px-4'>\n <div className='d-flex align-items-center'>\n <div style={{ backgroundImage: `url(${props.moviesAndTvIconUrl})` }} className={`${styles.icon}`}></div>\n <h1 className={`h2 ${styles.title} d-inline-block me-2`}>\n <Text namespace={namespace} phrase='heading' />\n </h1>\n {props.showPreviewingTooltip &&\n <div className='pt-1'>\n <Tooltip title={getPhrase('tooltip')} spanHack>\n <SvgContainer svg={InfoSvg} />\n </Tooltip>\n </div>\n }\n </div>\n <hr className='mt-2'/>\n <ExchangeAndTvLinks\n exchangeTvProductOption={props.settings?.exchangeTvProductOption}\n products={props.products}\n isPrimary={+PresentationLearningLevel[props.presentation?.learningLevel] === PresentationLearningLevel.Level_1}\n />\n {filteredWidgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.MoviesAndTv}\n settingsHash={props.settings}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.MoviesAndTv}\n widgetIndex={idx}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n settings={{\n hasTopicDirectories: props.settings?.hasTopicDirectories\n }}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n // TODO: Ideally we don't have to do this\n classification={null}\n hasTableOfContents={false}\n isEditing={false}\n setIsEmpty={() => {}}\n seeMoreLink={undefined}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n\n {showEmptyState && (\n <MoviesAndTvDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'streamable.companyDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamableCompanyDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadOnly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function StreamableCompanyDashboardEmptyState(props: StreamableCompanyDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('headingForStreamable')} />\n {!props.isReadOnly ? (\n <EmptyState.Heading>\n <Text phrase='headingForStreamable' />\n </EmptyState.Heading>\n ) : (\n <>\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='headingForCurator' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n\n",":local {\n $badge-base-height-md: 1.5rem; // 24px — original look\n $badge-base-height-lg: 2.375rem; // 38px — matches btn-lg\n\n .disabled {\n background-color: $gray-100;\n }\n\n .disabledHighlighted {\n background-color: lighten($info, 15%);\n }\n\n .badgeMd {\n height: $badge-base-height-md;\n margin-right: 0.25rem;\n }\n\n .badgeLg {\n height: $badge-base-height-lg;\n font-size: $font-size-lg;\n padding: 0 1rem;\n margin-right: 0.75rem;\n margin-bottom: 0.75rem;\n }\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 { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport styles from './audience-item.module.scss';\n\nconst namespace = 'shared.audienceItem';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction lowerCaseToTitleCase(str: string): string {\n return str.split(' ').map((s: string) => s.charAt(0).toUpperCase() + s.substring(1)).join(' ');\n}\n\nfunction getColourClass(highlight: boolean, isDisabled: boolean): string {\n if (highlight) return isDisabled ? `${styles.disabledHighlighted} text-light` : 'bg-gray-900 text-light';\n if (isDisabled) return `${styles.disabled} text-secondary`;\n return 'bg-light';\n}\n\ntype AudienceItemSize = 'md' | 'lg';\n\ninterface AudienceItemProps {\n audience: PresentationAudience;\n highlight: boolean;\n setAudience?: (audience: PresentationAudience, highlight: boolean) => void;\n isDisabled?: boolean;\n extraClasses?: string;\n size?: AudienceItemSize;\n}\n\nAudienceItem.defaultProps = {\n extraClasses: '',\n size: 'md'\n};\n\nconst SIZE_CLASS_MAP: Record<AudienceItemSize, string> = {\n md: styles.badgeMd,\n lg: styles.badgeLg\n};\n\nexport function AudienceItem(props: AudienceItemProps): React.ReactElement {\n const { audience, highlight, setAudience, isDisabled, extraClasses, size } = props;\n\n const className = classNames(\n getColourClass(highlight, isDisabled),\n isDisabled ? 'cursor-default' : 'cursor-pointer',\n SIZE_CLASS_MAP[size],\n extraClasses,\n 'lh-1 rounded-pill d-inline-block user-select-none'\n );\n\n const onClick = () => {\n if (isDisabled || !FunctionHelper.isFunction(setAudience))\n return;\n\n setAudience(audience, !highlight);\n };\n\n return (\n <button\n type='button'\n className={className}\n onClick={onClick}\n role='checkbox'\n aria-checked={highlight}\n aria-label={`${getPhrase('ariaFilter')} ${audience.name}`}\n disabled={isDisabled}\n >\n {lowerCaseToTitleCase(audience.name)}\n </button>\n );\n}\n","import * as React from 'react';\n\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Core } from 'libs/common/core';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AudienceItem } from 'libs/shared/apps/subjects/components/audience-item/AudienceItem';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\n\nconst namespace = 'subjects.audienceFilter';\n\ninterface AudienceFilterProps {\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n disabled?: boolean;\n appLink: Core.AppLink;\n disablePersist?: boolean;\n tooltip?: string;\n}\n\nexport function AudienceFilter(props: AudienceFilterProps): React.ReactElement {\n const { audiences, activeAudiences, appLink } = props;\n\n const isDisabled = props.disabled || !appLink;\n\n const [ , setActiveAudiences ] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n React.useEffect(() => {\n if (!props.disablePersist)\n setActiveAudiences(activeAudiences);\n }, [activeAudiences?.map(o => o.masterId).join(':')]);\n\n function onToggleAudience(audience: PresentationAudience, isSelected: boolean): void {\n if (isDisabled)\n return;\n\n const activeAudienceNames = isSelected ?\n [ ...(activeAudiences?.map(a => a.name) ?? []), audience.name ] :\n activeAudiences.map(a => a.name).filter(name => name !== audience.name);\n\n const getParams = () => {\n const otherParams = ObjectHelper.omit(appLink.params, ['a']);\n\n if (!activeAudienceNames.length)\n return otherParams;\n\n return Object.assign({}, otherParams, { a: activeAudienceNames });\n };\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params: getParams()\n }, { replace: true });\n }\n\n function onClickClearAudiences(): void {\n if (isDisabled)\n return;\n\n const params = ObjectHelper.omit(appLink.params, ['a']);\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params\n }, { replace: true });\n }\n\n if (!audiences || !audiences.length)\n return <></>;\n\n return (\n <Tooltip title={props.tooltip} spanHack>\n <div className='d-flex flex-wrap row-gap-2'>\n {audiences.map((a: PresentationAudience) => (\n <AudienceItem\n key={a.masterId}\n audience={a}\n highlight={!isDisabled && !!activeAudiences?.find(aa => aa.masterId === a.masterId)}\n setAudience={onToggleAudience}\n isDisabled={isDisabled}\n />\n ))}\n {(!isDisabled && !!activeAudiences && !!Object.keys(activeAudiences).length) && (\n <DivButton className='info-link d-inline-block ms-1' onClick={onClickClearAudiences}>\n <Text namespace={namespace} phrase='clear' />\n </DivButton>\n )}\n </div>\n </Tooltip>\n );\n}\n\nconst PARTIAL_AUDIENCES = PartialLoadingHelper.getPartialLoadingItems({ numItems: 6 });\n\nexport const PartialAudienceFilter = () => (\n <div className='d-flex flex-wrap row-gap-2'>\n {PARTIAL_AUDIENCES.map(({ width }, idx) => (\n <span\n key={idx}\n className='rounded-pill partial-loading-background me-1'\n dangerouslySetInnerHTML={{ __html: '&nbsp' }}\n style={{ width }}\n />\n ))}\n </div>\n);\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { LinkifyHelper } from 'libs/common/react/utils/LinkifyHelper';\n\nimport { EntityType, LocationContext } from 'libs/analytics/interfaces';\n\nimport { StreamableCompanyDashboardEmptyState } from 'libs/shared/apps/streamable-learning/components/company-dashboard/empty-state/StreamableCompanyDashboardEmptyState';\nimport { AudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader, PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { ExpandableQuestion } from 'libs/shared/components/expandable-question/ExpandableQuestion';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllCompanyWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { CalendarEventContentType, Company, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nconst namespace = 'streamable.companyDashboard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface StreamableCompanyDashboardProps {\n dashboard: CuratedDashboard;\n company: Company;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n audiences?: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllCompanyWidgetTemplates['appLinks'] & {\n audience: () => Core.AppLink,\n widgetWizard: () => Core.AppLink\n };\n scrollToWidgetId?: string;\n isReadOnly?: boolean;\n getBreadcrumbs?: () => Breadcrumb[];\n getBannerActions?: () => ActionOptions[];\n isBot?: boolean;\n lazyLoad?: boolean;\n commonVideoProps: CommonVideoProps;\n}\n\nexport function StreamableCompanyDashboard(props: StreamableCompanyDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n \n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard),\n props.activeAudiences?.map(a => a.masterId)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const onSetIsEmpty = React.useCallback((widgetId: string, isEmpty: boolean) => {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n setEmptyWidgets(newEmptyState);\n }, [ emptyWidgets, widgets ]);\n\n function shouldShowEmptyState(): boolean {\n if (!widgets?.length)\n return true;\n\n return Object.values(emptyWidgets).every(state => !!state);\n }\n\n const showEmptyState = shouldShowEmptyState();\n\n return (\n <>\n {!!widgets.length &&\n <>\n {props.company ?\n (\n <BannerHeader\n heading={props.company.name}\n logo={props.company.logo}\n logoBgColour={props.company.metadata?.colour}\n alignLogoLeft={!!props.company.logo || !!props.company.cover}\n banner={props.company.banner}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n blockColourClass={getBgColorClass(props.company.name, BG_COLOUR_CLASS_NAMES)}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n />\n ) : <PartialBannerHeader />\n }\n\n <div className='d-flex flex-column row-gap-3 py-3 mb-3 border-bottom'>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n\n <AudienceFilter\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n disabled={props.isReadOnly}\n appLink={props.widgetAppLinks?.audience()}\n />\n </div>\n\n {props.company.description && (\n <div className='mb-5'>\n <ExpandableQuestion\n id={props.company?.id}\n question={getPhrase('aboutUs')}\n answer={LinkifyHelper.linkifyText(props.company.description)}\n isBot={props.isBot}\n analyticsOptions={{\n entity: EntityType.Company,\n location: LocationContext.Dashboard\n }}\n />\n </div>\n )}\n\n <div>\n {widgets.map(widget => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Company}\n dashboardTarget={DashboardTargetType.Company}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n setIsEmpty={onSetIsEmpty}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadOnly}\n lazyLoad={props.lazyLoad}\n contentType={CalendarEventContentType.Livestream}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n\n // TODO: Ideally we don't have to do this\n classification={null}\n seeMoreLink={undefined}\n hasTableOfContents={false}\n onClickRemoveItem={undefined}\n settings={{\n hasTopicDirectories: false\n }}\n badgeComponent={null}\n />\n );\n })}\n </div>\n </>\n }\n\n {showEmptyState && (\n <StreamableCompanyDashboardEmptyState\n dashboard={props.dashboard}\n isReadOnly={props.isReadOnly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","@import '~styles/utils/include-media';\n:local{\n .pillTab {\n @include media('<=md') {\n li {\n min-width: 5rem;\n }\n }\n\n }\n}","import React from 'react';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\n\nimport styles from './streamable-header.module.scss';\n\nconst namespace = 'streamable.header';\n\nexport interface StreamableHeaderAppLinks {\n discover: Core.AppLink;\n calendar?: Core.AppLink;\n partners: Core.AppLink;\n}\n\ninterface StreamableHeaderProps {\n appLinks?: StreamableHeaderAppLinks;\n active: keyof StreamableHeaderAppLinks;\n isUpselling?: boolean;\n}\n\nexport function StreamableHeader(props: StreamableHeaderProps): JSX.Element {\n if (props.isUpselling)\n return <></>;\n\n const tabs = [{\n name: LanguageService.getPhrase(namespace, 'heading'),\n appLink: props.appLinks?.discover,\n active: props.active === 'discover',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'heading'),\n url: AppLinkHelper.getHref(props.appLinks?.discover)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n }];\n\n if (props.appLinks?.calendar)\n tabs.push({\n name: LanguageService.getPhrase(namespace, 'livestreams'),\n appLink: props.appLinks?.calendar,\n active: props.active === 'calendar',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'livestreams'),\n url: AppLinkHelper.getHref(props.appLinks?.calendar)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n });\n\n tabs.push({\n name: LanguageService.getPhrase(namespace, 'partners'),\n appLink: props.appLinks?.partners,\n active: props.active === 'partners',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'partners'),\n url: AppLinkHelper.getHref(props.appLinks?.partners)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n });\n\n return (\n <div className='py-3 text-center'>\n <PillTabSelector\n tabs={tabs}\n className={styles.pillTab}\n />\n </div>\n );\n}\n","import { DevError } from 'libs/common/backbone/errors/DevError';\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { GatedPermission, LocalPermissionName, LocalPermissionsLookup, PermissionName, PermissionsLookup } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAccessPolicy } from 'libs/shared/hooks/useAccessPolicy';\nimport { CurrentUser } from 'libs/shared/interfaces';\n\nimport { SharedViewModelKeys } from '../constants/SharedViewModelKeys';\n\nexport type HasPermissionsFunc = (filters: PermissionName | PermissionName[], type?: 'ALL' | 'ANY') => boolean;\nexport type HasLocalPermissionsFunc = (filters: LocalPermissionName | LocalPermissionName[]) => boolean;\n\n/**\n * Hidden - Don't see the feature at all\n * Hard gate - See the feature, but can't use it\n * Soft gate - See the feature, but can use it. UI should show it's a premium feature\n * Visible - See the feature and can use it\n * \n * - Sha\n */\nexport type GetGatedPermissionFunc = (name: PermissionName) => GatedPermission;\n\nfunction permissionCheck(permissions: PermissionsLookup, filters: PermissionName[], type?: 'ALL' | 'ANY'): boolean {\n if (!type)\n return !filters.find(p => !permissions[p]);\n\n if (type === 'ALL')\n return filters.every(p => permissions[p]);\n\n return filters.some(p => permissions[p]);\n}\n\nexport const usePermissions = () => {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const permissions = Flight.useBasicFetch<PermissionsLookup>(\n currentUser.hasCompleted &&\n UserRequests.permissions()\n );\n \n const { gatedPermissions } = useAccessPolicy();\n\n const [localPermissions] = useViewModel<LocalPermissionsLookup>(SharedViewModelKeys.LOCAL_PERMISSIONS);\n\n const hasPermissions: HasPermissionsFunc = (\n filters: PermissionName | PermissionName[],\n type?: 'ALL' | 'ANY'\n ) => {\n if (!permissions.hasCompleted || permissions.hasError)\n return false;\n\n if (!filters || !filters?.length)\n return true;\n\n if (!Array.isArray(filters))\n return !!permissions.data[filters];\n\n return permissionCheck(permissions.data, filters, type);\n };\n\n /**\n * Construct an enriched permission set object that contains server-side managed permissions\n * alongside local ones. I'm sure this will lead to further debate :joy:, but this\n * provides a mechanism to create locally derived permissions where the underlying data governing\n * it can be changed transparently. \n * \n * TODO (public): Review this approach prior to rolling out to prod. If we proceed, we can \n * DRY up this code a bit more.\n */\n const hasLocalPermissions: HasLocalPermissionsFunc = (\n filters: LocalPermissionName | LocalPermissionName[]\n ) => {\n if (!localPermissions)\n Core.ErrorHelper.throw(new DevError('Local Permissions should be registered during start up.'));\n\n if (!filters || !filters?.length)\n return true;\n\n if (!Array.isArray(filters))\n return !!localPermissions[filters];\n\n return !filters.find(p => !localPermissions[p]);\n };\n\n const getGatedPermission: GetGatedPermissionFunc = (\n name: PermissionName\n ) => {\n if (!permissions.hasCompleted || permissions.hasError)\n return 'hidden';\n\n if (!gatedPermissions.has(name))\n return permissions.data[name] ? 'visible' : 'hidden';\n\n return permissions.data[name] ? 'soft-gate' : 'hard-gate';\n };\n\n return {\n permissions: permissions.data,\n hasPermissions,\n hasLocalPermissions,\n getGatedPermission,\n isLoaded: permissions.hasCompleted\n };\n};\n\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'streamable.dashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamableDiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function StreamableDiscoverDashboardEmptyState(props: StreamableDiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { StreamableHeader, StreamableHeaderAppLinks } from 'libs/shared/apps/streamable-learning/components/header/StreamableHeader';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { StreamableDiscoverDashboardEmptyState } from './empty-state/StreamableDiscoverDashboardEmptyState';\n\nexport interface StreamableDiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: StreamableHeaderAppLinks;\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n commonVideoProps: CommonVideoProps;\n tutorialVideosContext?: TutorialVideosContext;\n isUpselling?: boolean;\n}\n\nexport function StreamableDiscoverDashboard(props: StreamableDiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <StreamableHeader\n active='discover'\n appLinks={props.headerAppLinks}\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n contentType={CalendarEventContentType.Livestream}\n preferences={widget.preferences}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n isTertiaryCustomerWithoutExchange={false}\n preventPopout\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n isUpselling={props.isUpselling}\n\n availablePresentations={undefined}\n classification={undefined}\n hasTableOfContents={undefined}\n onSubmitFeedback={undefined}\n settings={undefined}\n updatePreferences={undefined}\n seeMoreLink={undefined}\n onClickRemoveItem={undefined}\n badgeComponent={undefined}\n\n />\n );\n })}\n\n {showEmptyState && (\n <StreamableDiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Classification } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nconst namespace = 'subject.classificationHeaderDetails';\n\nconst Separator = ({ className }: { className: string }) =>\n <span className={className}>&bull;</span>;\n\ninterface ClassificationHeaderDetailsProps {\n classification: Classification;\n}\n\nexport function ClassificationHeaderDetails(props: ClassificationHeaderDetailsProps): React.ReactElement {\n const {\n dashboardVideoCount,\n childDashboardVideoCount,\n dashboardResourceCount,\n childDashboardResourceCount,\n childClassificationCount\n } = TopicsHelper.getCounts(props.classification);\n\n const videoCount = dashboardVideoCount + childDashboardVideoCount;\n const resourceCount = dashboardResourceCount + childDashboardResourceCount;\n\n return (\n <p className='mb-n1 font-size-normal fw-normal mt-1'>\n {!!childClassificationCount && (\n <Text\n namespace={namespace}\n phrase='topics'\n options={{ count: childClassificationCount.toLocaleString(), smartCount: childClassificationCount }}\n />\n )}\n\n {!!videoCount && (\n <>\n {childClassificationCount > 0 && <Separator className='mx-2' />}\n <Text\n namespace={namespace}\n phrase='videos'\n options={{ count: videoCount.toLocaleString(), smartCount: videoCount }}\n />\n </>\n )}\n {!!resourceCount && (\n <>\n <Separator className='mx-2' />\n <Text\n namespace={namespace}\n phrase='resources'\n options={{ count: resourceCount.toLocaleString(), smartCount: resourceCount }}\n />\n </>\n )}\n </p>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.curatedClassificationEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CuratedClassificationEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function CuratedClassificationEmptyState(props: CuratedClassificationEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('headingForNP')} />\n {!props.isReadonly ? (\n <EmptyState.Heading>\n <Text phrase='headingForNP' />\n </EmptyState.Heading>\n ) : (\n <>\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='headingForCurator' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n",":local{\n $dot-size: 0.75rem;\n $track-offset: -1rem;\n\n @mixin dot {\n &::before {\n position: absolute;\n left: -1.06rem;\n top: calc(50% - $dot-size/2);\n display: block;\n content: '';\n height: $dot-size;\n width: $dot-size;\n border-radius: 50%;\n background-color: $black;\n }\n }\n\n @mixin tocIndent($depth) {\n margin-left: map-get($spacers, 3) * $depth;\n }\n \n .itemsWrapper {\n border-left: 2px solid $black;\n padding-left: 0.625rem;\n }\n\n .anchorWrapper {\n padding: 0.625rem;\n text-decoration: none;\n position: relative;\n display: block;\n }\n .anchorWrapper:hover {\n background-color: $light-blue;\n text-decoration: none;\n cursor: pointer;\n }\n\n .anchorWrapper:first-child {\n &::after {\n display: block;\n content: '';\n background-color: $white;\n height: calc(50% - $dot-size/2 + 0.05rem);\n width: 0.625rem;\n top: -0.05rem;\n position: absolute;\n left: $track-offset;\n }\n }\n .anchorWrapper:last-child {\n &::after {\n display: block;\n content: '';\n background-color: $white;\n height: calc(50% - $dot-size/2);\n width: 0.625rem;\n position: absolute;\n bottom: 0;\n left: $track-offset;\n }\n }\n\n .default {\n @include dot\n }\n\n .selectedItem {\n background-color: $gray-100;\n font-weight: 500;\n @include dot\n }\n \n .disabled:hover {\n cursor: default;\n background-color: $white;\n }\n .disabled{\n pointer-events:none\n }\n\n .floatIcon {\n position: absolute;\n right: 0;\n width: fit-content;\n padding: 0;\n .arrowIcon {\n display: none;\n }\n .listIcon {\n display: block;\n }\n &:hover {\n .listIcon {\n display: none;\n }\n .arrowIcon {\n display: block;\n }\n }\n }\n\n .tocIndent1 {\n @include tocIndent(1);\n }\n\n .tocIndent2 {\n @include tocIndent(2);\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { ScrollHelper } from 'libs/common/backbone/utils/ScrollHelper';\n\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\n\nimport styles from './table-of-contents-list.module.scss';\n\nexport interface TableOfContentsItem<T=string> {\n name: string;\n id: T;\n tocIndentation?: number;\n}\n\ninterface TableOfContentsProps<T> {\n items: TableOfContentsItem<T>[];\n activeId: string;\n appLink?: Core.AppLink;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n // set to true if the TOC is controlled by a local state rather than query params\n localState?: boolean;\n getAppLink?: (args: TableOfContentsItem<T>) => Core.AppLink;\n onItemClick?: (args: TableOfContentsItem<T>) => void;\n}\n\nexport function TableOfContentsList<T extends string>(props: TableOfContentsProps<T>): JSX.Element {\n const analyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.Widget,\n location: LocationContext.TableOfContents\n };\n\n function onItemSelect(item: TableOfContentsItem<T>) {\n ScrollHelper.preventScrollTop();\n props.setControlledId(item.id);\n \n props.onItemClick?.(item);\n \n setTimeout(() => document.getElementById(item.id)?.focus());\n }\n\n function getTocIndentClass(item: TableOfContentsItem<T>): string {\n if (item.tocIndentation === 1)\n return styles.tocIndent1;\n \n if (item.tocIndentation === 2)\n return styles.tocIndent2;\n\n return '';\n }\n\n return (\n <div className={`${styles.itemsWrapper}`}>\n {props.items.map((item, idx) => {\n if (props.localState) {\n return (\n <DivButton\n key={item.id}\n className={`${styles.anchorWrapper} ${props.activeId === item.id ? styles.selectedItem : ''}`}\n onClick={() => {\n onItemSelect(item);\n }}\n >\n <div className={`${!props.activeId && idx === 0 ? styles.default : ''} `}>\n {item.name}\n </div>\n </DivButton>\n );\n }\n\n return (\n <AppLink\n key={item.id}\n appLink={props.getAppLink(item)}\n appLinkOptions={{ replace: true }}\n className={`${styles.anchorWrapper} ${props.activeId === item.id ? styles.selectedItem : ''}`}\n onClick={() => {\n onItemSelect(item);\n }}\n analyticsData={{\n ...props.analyticsData,\n id: item.id,\n name: item.name\n }}\n analyticsOptions={analyticsOptions}\n >\n <div className={`${!props.activeId && idx === 0 ? styles.default : ''} ${getTocIndentClass(item)}`}>\n {item.name}\n </div>\n </AppLink>\n );\n })}\n </div>\n );\n}\n","import React from 'react';\n\nexport function TableOfContentsSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n fillRule='evenodd'\n d='M5.5 8a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3m4-2a.5.5 0 0 0 0 1h10a.5.5 0 0 0 0-1zM9 11.5a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1h-10a.5.5 0 0 1-.5-.5M5.5 13a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M9 16.5a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1h-10a.5.5 0 0 1-.5-.5M5.5 18a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3'\n clipRule='evenodd'\n />\n </svg>\n );\n}\n","$top-nav-height: 4.1875rem;\n$cv-banner-height: calc(100vw * 22 / 120);\n$filters-area: 7.87rem;\n\n.container {\n position: sticky;\n top: 6.25rem;\n z-index: 80;\n}\n\n.mobile {\n position: fixed;\n top: calc($top-nav-height + $cv-banner-height + $filters-area);\n z-index: 80;\n right: 0;\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { TableOfContentsList } from 'libs/shared/components/table-of-contents-list/TableOfContentsList';\nimport { TableOfContentsSvg } from 'libs/shared/images/svg/objects/TableOfContentsSvg';\nimport { CuratedWidget } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport styles from './table-of-contents.module.scss';\n\ninterface TableOfContentsContainerProps {\n widgets: CuratedWidget[];\n title: string;\n activeId: string;\n appLink?: Core.AppLink;\n clickable?: boolean;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n isSmallScreen?: boolean;\n}\ninterface TableOfContentsProps extends TableOfContentsContainerProps {\n getAppLink: (widget: CuratedWidget) => Core.AppLink;\n}\n\nfunction TableOfContentsMobile(props: TableOfContentsProps) {\n const [ isExpanded, setIsExpanded ] = React.useState(false);\n\n function logUserAction() {\n const analyticsOptions = {\n actionType: !isExpanded ? UserAction.Open : UserAction.Hide,\n entity: EntityType.TableOfContents,\n location: LocationContext.Dashboard\n };\n\n AnalyticsHelper.logUserAction(props.analyticsData, analyticsOptions);\n }\n\n function onClickIcon() {\n setIsExpanded(!isExpanded);\n logUserAction();\n }\n\n return (\n <div className={`${styles.mobile} d-inline-flex gap-1`}>\n \n {isExpanded && (\n <div className='bg-white px-3 pt-3 pb-2 border border-dark rounded-1 ps-3'>\n <h2 className='h5'>{props.title}</h2>\n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n onItemClick={() => setIsExpanded(false)}\n />\n </div>\n )}\n <div className={styles.container}>\n <IconButton\n className='btn btn-outline-dark'\n svg={TableOfContentsSvg}\n onClick={onClickIcon}\n />\n </div>\n </div>\n );\n}\n\nfunction TableOfContents(props: TableOfContentsProps): JSX.Element {\n return (\n <aside className='col-3 order-1'>\n <div className={`${styles.container} ps-3`}>\n <h2 className='h5'>{props.title}</h2>\n \n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n />\n </div>\n </aside>\n );\n}\n\nexport function TableOfContentsContainer(props: TableOfContentsContainerProps): JSX.Element {\n function getAppLink(widget: CuratedWidget): Core.AppLink {\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n \n const params: HashObject = currentAppLink.params ?\n { ...(currentAppLink.params as HashObject) } :\n {};\n\n params.tocId = widget.id;\n\n return {\n ...currentAppLink,\n params\n };\n }\n\n return (\n <>\n {!props.isSmallScreen ?\n <TableOfContents {...props} getAppLink={getAppLink} /> :\n <TableOfContentsMobile {...props} getAppLink={getAppLink} />\n }\n </>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'subjects.teacherOnlyEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface TeacherOnlyEmptyStateProps {\n imageUrl: string;\n ctaAppLink?: () => Core.AppLink;\n}\n\nexport function TeacherOnlyEmptyState(props: TeacherOnlyEmptyStateProps): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('heading')} />\n <EmptyState.Heading>\n <Text phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text phrase='info' />\n </EmptyState.Info>\n\n <EmptyState.Cta\n text={getPhrase('cta')}\n appLink={props.ctaAppLink?.()}\n className='btn btn-dark'\n />\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { CuratedDashboard, CuratedDashboardCollection, CuratedWidget, CuratedWidgetContent, CuratedWidgetQueryParams, CurrentUser, DashboardStatus, DashboardUserType, Presentation, WidgetPreference } from 'libs/shared/interfaces';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { HardCoded } from '../constants/HardCoded';\nimport { ContentRegion } from '../enums/ContentRegion';\nimport { WidgetTemplate } from '../enums/WidgetTemplate';\nimport { MasterTypeHelper } from '../utils/MasterTypeHelper';\nimport { ThemeAssetHelper } from '../utils/ThemeAssetHelper';\n\ninterface GetDashboardWidgetContentOptions {\n hideTigTag?: boolean;\n hideTwig?: boolean;\n cursor?: string;\n}\n\nconst TWIG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Twig.EnglandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.InternationalSecondary),\n ...Object.values(HardCoded.Classifications.Twig.ScotlandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.NewZealandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.CanadaMiddle),\n ...Object.values(HardCoded.Classifications.Twig.CanadaHigh)\n]);\n\nconst TIG_TAG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Tigtag.EnglandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.InternationalPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.ScotlandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.NewZealandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaElementary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaMiddle)\n]);\n\nfunction getQueryParamsKey(queryParams: CuratedWidgetQueryParams): string {\n return Object.keys(queryParams)\n .map((key: keyof CuratedWidgetQueryParams) => queryParams[key])\n .join(':');\n}\n\nfunction getNamespaceKey(queryParams: CuratedWidgetQueryParams, options: GetDashboardWidgetContentOptions): string {\n if (!options.cursor)\n return getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]));\n\n return `${getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]))}:${options.cursor}`;\n}\n\nfunction shouldNormalizeWidgetRequest(\n template: WidgetTemplate\n): boolean {\n if (template === WidgetTemplate.EditableCoverFixedPillListSmall)\n return false;\n\n return true;\n}\n\nexport const DashboardRequests = {\n classificationDashboard(\n classificationId: string,\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n dashboardId?: string | null\n ): Flight.PublicRequest {\n const queryParamOpts = {\n target: `classification:${classificationId}`,\n status: statuses,\n userType\n };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n key: `classification:dashboard:${classificationId}:${userType}:${dashboardId}:${statuses?.join(':')}`,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n }\n };\n },\n\n dashboardWidgetContent(\n id: string,\n queryParams: CuratedWidgetQueryParams = {},\n template?: WidgetTemplate,\n presentation?: Presentation,\n options: GetDashboardWidgetContentOptions = {}\n ): Flight.PublicRequest {\n const queryParamsWithCursor = { ...queryParams, cursor: options.cursor };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/widgets/${id}`, queryParamsWithCursor),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/widgets/${id}`, queryParamsWithCursor),\n regionScoped: true,\n key: `widget:${id}:${getQueryParamsKey(queryParamsWithCursor)}`,\n formatData: (widget: CuratedWidget) => {\n const formatted = WidgetHelper.formatResponseData(widget, presentation);\n\n if (Array.isArray(formatted.content)) {\n formatted.content = formatted.content.map(\n entity => MasterTypeHelper.isClassification(entity) ?\n ThemeAssetHelper.applyThemeToClassification(entity) :\n entity\n ) as CuratedWidgetContent;\n }\n\n if (!options.hideTigTag && !options.hideTwig)\n return formatted;\n\n // Filter out the Twig topics for users who don't have access to the Twig library\n if (Array.isArray(formatted.content)) {\n const newContent = formatted.content.filter(entity => {\n if (MasterTypeHelper.isClassification(entity)) {\n if (TIG_TAG_TOPIC_IDS.has(entity.id))\n return !options.hideTigTag;\n\n if (TWIG_TOPIC_IDS.has(entity.id))\n return !options.hideTwig;\n\n return true;\n }\n \n return true;\n }) as CuratedWidgetContent;\n \n formatted.content = newContent;\n }\n \n return formatted;\n },\n normalizeOptions: {\n namespace: getNamespaceKey(queryParams, options)\n },\n normalize: shouldNormalizeWidgetRequest(template)\n };\n },\n\n getDashboard(\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n target: string,\n curriculumIds?: string[],\n dashboardId?: string,\n contentRegion?: ContentRegion,\n success?: (data: CuratedDashboard) => void\n ): Flight.PublicRequest {\n const queryParamOpts: HashObject = {\n target,\n status: statuses,\n userType\n };\n\n if (curriculumIds?.length)\n queryParamOpts['widgets.curriculum'] = curriculumIds;\n\n if (contentRegion)\n queryParamOpts.contentRegion = contentRegion;\n\n const key = `dashboard:${target}:${userType}:${dashboardId}:${statuses.join(':')}:${contentRegion ?? ''}`;\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n regionScoped: true,\n key,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n },\n success\n };\n },\n\n updateWidgetPreferences(widgetId: string, preferences: WidgetPreference[], currentUser: CurrentUser): Flight.Request {\n return {\n url: `{gateway}/v1/discover/widgets/${widgetId}/preferences`,\n key: 'update:widget:preferences',\n invalidationKeys: [`widget:${widgetId}`],\n type: HttpVerbs.PUT,\n data: {\n userId: currentUser.id,\n customerId: currentUser.customerId,\n metadata: preferences\n }\n };\n }\n};\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { CuratedDashboard, CuratedMediaWidget, CuratedWidget, PresentationAudience, Video } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nexport interface Response {\n widgets: CuratedWidget[];\n\n videoList?: Video[];\n videoListWidgetId?: string;\n}\n\n/**\n * This hook helps us with custom logic for to display system generated dashboards in a slightly\n * different way.\n */\nexport function useGetTopicsWidgets(dashboard: CuratedDashboard, activeAudiences: PresentationAudience[]): Response {\n const {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget\n } = React.useMemo(() => {\n if (!dashboard) {\n return {\n isSystemGeneratedDashboard: false,\n systemGeneratedVideoWidget: null\n };\n }\n\n const isSystemGeneratedDashboard = CuratedDashboardHelper.isSystemGeneratedDashboard(dashboard.widgets);\n\n return {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget: dashboard.widgets.find(widget => {\n return (\n widget.widgetId === WidgetTypeId.ClassificationPinnedVideos &&\n widget.templateId !== WidgetTemplate.ThumbnailVerticalList\n );\n })\n };\n }, [dashboard?.id]);\n\n const systemGeneratedVideoContent = Flight.useBasicFetch<CuratedMediaWidget<Video[]>>(\n !!systemGeneratedVideoWidget &&\n DashboardRequests.dashboardWidgetContent(\n systemGeneratedVideoWidget?.id,\n CuratedDashboardHelper.getWidgetParams(\n systemGeneratedVideoWidget.widgetId,\n systemGeneratedVideoWidget.templateId,\n CuratedDashboardHelper.getDashboardTargetType(dashboard),\n activeAudiences?.map(a => a.masterId)\n ),\n systemGeneratedVideoWidget?.templateId\n )\n );\n\n // Non system generated dashboards are returned as per usual\n if (!isSystemGeneratedDashboard)\n return { widgets: ArrayHelper.sortBy(dashboard?.widgets, 'index') };\n\n // System generated dashboard have the video widget removed and returned as a separate video list\n return {\n widgets: dashboard?.widgets?.filter(widget => {\n if (widget.widgetId !== WidgetTypeId.ClassificationPinnedVideos)\n return true;\n\n if (widget.templateId === WidgetTemplate.ThumbnailVerticalList)\n return true;\n\n return false;\n }) ?? [],\n videoList: systemGeneratedVideoContent.data?.content ?? [],\n videoListWidgetId: systemGeneratedVideoWidget?.id\n };\n}\n","import React from 'react';\n\ntype TableOfContentsActiveOption = {\n setActiveId: (id: string) => void,\n headingElements: Element[],\n controlledId?: string,\n setControlledId?: (arg: string) => void\n};\n\n// a smooth scroll emits scroll events every frame; silence this long means it has finished.\n// Safari has no scrollend event, so completion is detected by settling instead\nconst SCROLL_SETTLE_MS = 150;\n// ignore sub-pixel scrollY jitter when deciding the user has scrolled back against the autoscroll\nconst SCROLL_REVERSAL_BUFFER_PX = 2;\n\nexport const useTableOfContentsActiveHeading = (\n { setActiveId, headingElements, controlledId, setControlledId }: TableOfContentsActiveOption\n) => {\n const scrollPositionRef = React.useRef(0);\n\n React.useEffect(() => {\n const callback = (headings: IntersectionObserverEntry[]) => {\n headings.forEach(heading => {\n if (controlledId) {\n setActiveId(controlledId);\n return;\n }\n if (heading.isIntersecting) {\n setActiveId(heading.target.id);\n scrollPositionRef.current = window.scrollY;\n } else {\n const scrollDistance = scrollPositionRef.current - window.scrollY;\n const isScrollingUp = scrollDistance > 0;\n const curIndex = headingElements.findIndex(h => h.id === heading.target.id);\n const prevHeading = headingElements[curIndex - 1];\n if (isScrollingUp && prevHeading?.id) {\n setActiveId(prevHeading?.id);\n }\n }\n });\n };\n\n const observer = new IntersectionObserver(callback, {\n // rootMargin top: same as the cv-nav-height\n rootMargin: '-67px 0px -80% 0px'\n });\n\n headingElements.forEach(element => observer.observe(element));\n\n return () => {\n observer.disconnect();\n };\n }, [ setActiveId, headingElements.length, controlledId ]);\n\n React.useEffect(() => {\n // controlledId tracks the heading post manual selection on the TOC.\n // Its absence means that the user is navigating through scrolling\n if (!controlledId || !setControlledId)\n return;\n\n let settleTimer: number;\n let hasSettled = false;\n let travelDirection = 0;\n let scrollTarget = window.scrollY;\n\n const restartSettleTimer = () => {\n window.clearTimeout(settleTimer);\n settleTimer = window.setTimeout(() => {\n hasSettled = true;\n }, SCROLL_SETTLE_MS);\n };\n\n const onScroll = () => {\n const delta = window.scrollY - scrollTarget;\n\n if (!travelDirection)\n travelDirection = Math.sign(delta); // sets initial travel direction\n\n // captures user taking over from autoscroll if the direction changes\n // might not be necessary given the distance travelled is quite short for reverse scrolling to happen\n const hasReversed = !!travelDirection\n && Math.sign(delta) === -travelDirection\n && Math.abs(delta) > SCROLL_REVERSAL_BUFFER_PX;\n\n if (hasSettled || hasReversed) {\n setControlledId('');\n return;\n }\n\n if (Math.sign(delta) === travelDirection)\n scrollTarget = window.scrollY;\n\n restartSettleTimer();\n };\n\n // when the target heading is already in position no scroll events fire at all,\n // so start the countdown immediately to let the next user scroll release the pin\n restartSettleTimer();\n window.addEventListener('scroll', onScroll, { passive: true });\n\n return () => {\n window.clearTimeout(settleTimer);\n window.removeEventListener('scroll', onScroll);\n };\n }, [ controlledId, setControlledId ]);\n};\n\n","import React from 'react';\n\nimport { usePrevious } from './usePrevious';\n\nconst HEADER_OFFSET = 80; // Size of header + some extra spacing\n\nexport const useTableOfContentsScroll = (elements: Element[], activeId: string) => {\n const [ hasDoneInitialScroll, setHasDoneInitialScroll ] = React.useState(false);\n\n const previousId = usePrevious(activeId);\n const currentId = activeId;\n\n React.useLayoutEffect(() => {\n if (!hasDoneInitialScroll || previousId !== currentId) {\n const target = elements.find(heading => heading && (heading?.id === currentId));\n\n if (target) {\n const rec = target.getBoundingClientRect();\n\n window.scrollBy({\n top: rec.top - HEADER_OFFSET,\n behavior: 'smooth'\n });\n \n if (!hasDoneInitialScroll)\n setHasDoneInitialScroll(true);\n }\n }\n }, [ elements, previousId, currentId, hasDoneInitialScroll ]);\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { BellFilledSvg } from 'libs/shared/images/svg/objects/BellFilledSvg';\nimport { BellSvg } from 'libs/shared/images/svg/objects/BellSvg';\nimport { Classification } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.classificationComingSoon';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ComingSoonProps {\n data: Classification;\n onToggleFollow?: () => void;\n canFollowSubjects: boolean;\n imageUrl: string;\n showFollowButtonSpinner: boolean;\n showSignUp: boolean;\n signUpAppLink: Core.AppLink;\n}\n\nexport function ClassificationComingSoon(props: ComingSoonProps): JSX.Element {\n const isFollowing = !!props.data.followers?.data?.length;\n function onClick(): void {\n props.onToggleFollow?.();\n }\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState className='pt-0'>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('comingSoon')} />\n\n <EmptyState.Heading>\n <Text phrase='comingSoon' />\n </EmptyState.Heading>\n\n <EmptyState.Info>\n <Text phrase={props.showSignUp ? 'infoAnon' : 'info'} />\n </EmptyState.Info>\n\n {props.canFollowSubjects && (\n <ActionButton\n svg={isFollowing ? BellFilledSvg : BellSvg}\n onClick={onClick}\n showSpinner={props.showFollowButtonSpinner}\n className={`btn follow-btn me-2 ${isFollowing ? 'btn-outline-dark' : 'btn-dark'}`}\n >\n <Text phrase={isFollowing ? 'following' : 'follow'} />\n </ActionButton>\n )}\n\n {props.showSignUp && !props.canFollowSubjects && (\n <AppLink\n appLink={props.signUpAppLink}\n className='btn btn-dark d-none d-lg-inline-block'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.ClassificationComingSoon,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n }}\n analyticsData={{}}\n tag='button'\n >\n {getPhrase('signUp')}\n </AppLink>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { AudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\ninterface ClassificationDashboardAudiencesProps {\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n appLink: Core.AppLink;\n disabled: boolean;\n disablePersist: boolean;\n tooltip: string;\n}\n\nexport function ClassificationDashboardAudiences(props: ClassificationDashboardAudiencesProps): JSX.Element {\n return (\n <AudienceFilter\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n disabled={props.disabled}\n appLink={props.appLink}\n disablePersist={props.disablePersist}\n tooltip={props.tooltip}\n />\n );\n}\n","import React from 'react';\n\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { ClassificationTab } from '../components/classification-dashboard/classification-tabs/ClassificationTabs';\n\ninterface ViewModel {\n tab: ClassificationTab;\n on: boolean;\n}\n\nexport function useDirectoryTabProductTipSwitcher(initialTab?: ClassificationTab) {\n const initialState: ViewModel = {\n on: false,\n tab: initialTab || 'new-releases'\n };\n\n const [ viewModel, setViewModel ] = useViewModel<ViewModel>('directory:product:tip:switcher', initialState);\n\n React.useEffect(() => {\n if (!initialTab)\n return;\n\n setViewModel('tab', initialTab);\n }, [initialTab]);\n\n React.useEffect(() => {\n let interval: number = null;\n\n if (viewModel.on) {\n interval = window.setInterval(() => {\n if (viewModel.tab === 'new-releases' || viewModel.tab === 'all-topics')\n setViewModel('tab', viewModel.tab === 'new-releases' ? 'all-topics' : 'new-releases');\n else\n setViewModel('tab', viewModel.tab === 'curated-topic' ? 'video-list' : 'curated-topic');\n }, 2000);\n }\n\n return () => {\n window.clearInterval(interval);\n };\n }, [ viewModel.on, viewModel.tab ]);\n\n return {\n tab: viewModel.tab,\n isHighlighting: viewModel.on,\n start: () => setViewModel('on', true),\n stop: () => {\n setViewModel({\n on: false,\n tab: initialTab || viewModel.tab\n });\n }\n };\n}\n",":local {\n .curatedTopicTab {\n min-width: 6rem !important;\n }\n \n .tabTransition {\n transition: background-color .5s ease-in-out;\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTab, PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\nimport { Breakpoints, useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { GridSvg } from 'libs/shared/images/svg/objects/GridSvg';\nimport { RectanglesSvg } from 'libs/shared/images/svg/objects/RectanglesSvg';\nimport { SparkleSvg } from 'libs/shared/images/svg/objects/SparkleSvg';\nimport { WidgetSeriesSvg } from 'libs/shared/images/svg/widgets/WidgetSeriesSvg';\nimport { Classification, Presentation } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { useDirectoryTabProductTipSwitcher } from '../../../hooks/useDirectoryTabProductTipSwitcher';\n\nimport styles from './classification-tabs.module.scss';\n\nconst namespace = 'shared.classificationDashboard';\n\nexport type ClassificationTab = 'new-releases' | 'all-topics' | 'curated-topic' | 'curriculum';\n\nfunction getTabs(\n props: ClassificationTabsProps,\n breakpoints: Breakpoints,\n activeTab: ClassificationTab,\n isHighlighting: boolean\n): PillTab[] {\n const showText = breakpoints.lg || breakpoints.xl || breakpoints.xxl || breakpoints.xs;\n\n function getTopicTabClassName(): string {\n let className = isHighlighting ? styles.tabTransition : '';\n\n if (breakpoints.xs)\n return className + ' w-100';\n\n if (showText)\n return className = ` ${styles.curatedTopicTab}`;\n\n return className;\n }\n\n if (TopicsHelper.isTopLevelTopic(props.classification)) {\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'newReleases') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'new-releases',\n svg: SparkleSvg,\n analyticsData: {\n id: 'new-releases',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'newReleases'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'allTopics') : '',\n appLink: props.appLinks?.classificationDirectory?.(props.classification),\n active: activeTab === 'all-topics',\n svg: GridSvg,\n analyticsData: {\n id: 'all-topics',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'allTopics'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationDirectory?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n }\n\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'topic') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'curated-topic',\n svg: RectanglesSvg,\n analyticsData: {\n id: 'curated-topic',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'topic'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: getTopicTabClassName()\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'curriculum') : '',\n appLink: props.appLinks?.classificationCurriculum?.(props.classification),\n active: activeTab === 'curriculum',\n svg: WidgetSeriesSvg,\n analyticsData: {\n id: 'curriculum',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'curriculum'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationCurriculum?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n}\n\ninterface ClassificationTabsProps {\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n classification: (classification: Classification | null) => Core.AppLink,\n classificationDirectory: (classification: Classification) => Core.AppLink,\n classificationCurriculum: (classification: Classification) => Core.AppLink\n };\n activeTab: ClassificationTab;\n}\n\nexport function ClassificationTabs(props: ClassificationTabsProps): JSX.Element {\n const breakpoints = useBreakpoints();\n const { tab, isHighlighting } = useDirectoryTabProductTipSwitcher(props.activeTab);\n\n return (\n <PillTabSelector\n borderRadius='sm'\n className={breakpoints.xs ? 'w-100' : ''}\n listClassName='d-flex flex-nowrap'\n tabs={getTabs(props, breakpoints, tab, isHighlighting)}\n />\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Classification, CuratedDashboard, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ClassificationDashboardAudiences } from '../audiences/ClassificationDashboardAudiences';\nimport { ClassificationTab, ClassificationTabs } from '../classification-tabs/ClassificationTabs';\n\nfunction shouldHideAudiences(\n audiences: PresentationAudience[],\n activeAudiences: PresentationAudience[],\n activeTab: ClassificationTab,\n isEmpty: boolean,\n isComingSoon: boolean\n): boolean {\n if (isComingSoon)\n return true;\n\n if (isEmpty && !activeAudiences?.length)\n return true;\n\n if (!AudienceHelper.shouldShowAudiences(audiences))\n return true;\n\n if (activeTab === 'curriculum')\n return true;\n\n return false;\n}\n\ninterface ClassificationDashboardNavProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n audience: () => Core.AppLink,\n classification: (classification: Classification | null) => Core.AppLink,\n classificationDirectory: (classification: Classification) => Core.AppLink,\n classificationCurriculum: (classification: Classification) => Core.AppLink\n };\n activeTab: ClassificationTab;\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n getBreadcrumbs: () => Breadcrumb[];\n\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isComingSoon: boolean;\n isEmpty: boolean;\n isViewingCurrentPresentation: boolean;\n disableAudiences: boolean;\n audienceTooltip: string;\n\n // Forces audiences to be hidden regardless of shouldHideAudiences' own rules (e.g. channel topic dashboards)\n forceHideAudiences?: boolean;\n}\n\nexport function ClassificationDashboardNav(props: ClassificationDashboardNavProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const hideAudiences = props.forceHideAudiences || shouldHideAudiences(\n props.audiences,\n props.activeAudiences,\n props.activeTab,\n props.isEmpty,\n props.isComingSoon\n );\n\n function canShowTabs(): boolean {\n if (!props.classification || !props.dashboard)\n return false;\n\n if (CuratedDashboardHelper.isSystemGeneratedDashboard(props.dashboard.widgets))\n return false;\n\n /**\n * For our top-level topics, we can show the topic tab if the topic has a directory dashboard.\n */\n if (TopicsHelper.isTopLevelTopic(props.classification))\n return props.hasTopicDirectoryDashboard;\n\n /**\n * For our curated topics, we can show the curriculum tab if the topic has one, which it should\n */\n if (props.classification.externalMetadata?.isCurated && props.hasTopicCurriculumDashboard)\n return true;\n\n return false;\n }\n\n function getContainerClass(): string {\n let className = 'd-flex flex-column py-3 mb-3';\n\n if (!props.isComingSoon)\n className += ' border-bottom';\n\n if ((canShowTabs() || hideAudiences) && !breakpoints.xs)\n return className;\n\n return className + ' row-gap-3';\n }\n\n function getTopRowClass(): string {\n if (hideAudiences) {\n if (breakpoints.xs)\n return 'd-flex flex-column justify-content-between row-gap-3';\n\n return 'd-flex align-items-center justify-content-between';\n }\n\n let className = '';\n\n className += 'd-flex align-items-center justify-content-between mb-1';\n\n if (breakpoints.xs)\n className += ' row-gap-3 mb-0';\n\n return className;\n }\n\n function getBottomRowClass(): string {\n let className = 'd-flex align-items-end justify-content-between';\n\n if (breakpoints.xs)\n className += ' row-gap-3 flex-wrap';\n\n return className;\n }\n\n return (\n <div className={getContainerClass()}>\n <div className={getTopRowClass()}>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n\n {canShowTabs() && hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n\n <div className={getBottomRowClass()}>\n {!hideAudiences && (\n <ClassificationDashboardAudiences\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n appLink={props.appLinks.audience?.()}\n disabled={props.disableAudiences}\n tooltip={props.audienceTooltip}\n disablePersist={!props.isViewingCurrentPresentation}\n />\n )}\n\n {canShowTabs() && !hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsOptions, HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { ClassificationHeaderDetails } from 'libs/shared/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails';\nimport { CuratedClassificationEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState';\nimport { TableOfContentsContainer } from 'libs/shared/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents';\nimport { TeacherOnlyEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState';\nimport { useGetTopicsWidgets } from 'libs/shared/apps/subjects/hooks/useGetTopicsWidgets';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { ExpandableTextInline } from 'libs/shared/components/expandable-text-inline/ExpandableTextInline';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { VideoList } from 'libs/shared/components/video-list/VideoList';\nimport { WidgetHeader } from 'libs/shared/components/widgets/curated-widgets/components/header/WidgetHeader';\nimport { InfiniteWidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/InfiniteWidgetContainerView';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllClassificationWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { ClassificationType } from 'libs/shared/enums/ClassificationType';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { LocalPermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { useTableOfContentsActiveHeading } from 'libs/shared/hooks/useTableOfContentsActiveHeading';\nimport { useTableOfContentsScroll } from 'libs/shared/hooks/useTableOfContentsScroll';\nimport { CalendarEvent, CalendarEventContentType, Classification, CuratedDashboard, CuratedWidget, CuratedWidgetQueryParams, CurriculumData, DashboardStatus, DashboardTargetType, InteractiveMetadata, PartnerProfile, Presentation, PresentationAudience, Resource } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { ClassificationComingSoon } from './classification-coming-soon/ClassificationComingSoon';\nimport { ClassificationDashboardNav } from './classification-dashboard-nav/ClassificationDashboardNav';\nimport { ClassificationTab } from './classification-tabs/ClassificationTabs';\n\nconst namespace = 'shared.classificationDashboard';\n\nfunction isHeadingWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.Blurb && widget.templateId === WidgetTemplate.Heading;\n}\n\nfunction isTopicWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.CuratedClassifications || widget.widgetId === WidgetTypeId.Classifications;\n}\n\n// ClassificationAllVideos is the only widget type that supports infinite-scroll pagination so far\nconst InfiniteFetchWidgetIds: WidgetTypeId[] = [WidgetTypeId.ClassificationAllVideos];\n\nfunction shouldInfiniteFetch(widgets: CuratedWidget[], index: number): boolean {\n const currentWidget = widgets[index];\n\n if (!currentWidget) return false;\n\n return InfiniteFetchWidgetIds.includes(currentWidget.widgetId) && index === widgets.length - 1;\n}\n\n/**\n * Mirrors WidgetHelper's per-widget empty check (which InfiniteWidgetContainerView can't infer\n * on its own, since a completed fetch always returns one \"page\" object regardless of whether the\n * widget's own content is empty).\n */\nfunction isWidgetContentEmpty(widgets: CuratedWidget[]): boolean {\n const widget = widgets?.[0];\n\n if (!widget) return true;\n\n if (WidgetHelper.hasNoContent(widget.widgetId)) return false;\n\n if (!widget.content) return true;\n\n return Array.isArray(widget.content) && !widget.content.length;\n}\n\nexport interface ClassificationDashboardProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n resourceThumbnailFallbackImageUrl: string;\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isTertiaryCustomerWithoutExchange: boolean;\n tab: ClassificationTab;\n specialEvent?: CalendarEvent;\n curriculums: CurriculumData;\n channel?: PartnerProfile;\n\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n /**\n * Only needed by consumers that support cursor-paginated widgets (currently just\n * WidgetTypeId.ClassificationAllVideos). If omitted, that widget type falls back to fetching\n * its first page only via `getWidgetContentRequest`, with no \"load more\" pagination.\n */\n getWidgetContentRequestWithCursor?: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n cursor?: string\n ) => Flight.Request;\n\n getBannerActions?: () => ActionOptions[];\n getBreadcrumbs?: () => Breadcrumb[];\n onToggleFollow?: (classification: Classification, locationContext: LocationContext) => void;\n canFollowSubjects: boolean;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n onDownloadAllClick?: (resources: Resource[], fileName: string, analyticsData?: HashObject) => void;\n\n appLinks?: AllClassificationWidgetTemplates['appLinks'] & {\n signUp: () => Core.AppLink,\n widgetWizard: () => Core.AppLink,\n previewQuestions: (interactive: InteractiveMetadata) => Core.AppLink,\n classificationCurriculum: (classification: Classification) => Core.AppLink,\n audience: () => Core.AppLink\n };\n\n imageCdnUrl: string;\n imageUrls?: AllClassificationWidgetTemplates['imageUrls'];\n emptyImageUrl: string;\n comingSoonImageUrl?: string;\n\n analyticsOptions?: AnalyticsOptions;\n analyticsData?: HashObject;\n\n scrollToWidgetId?: string;\n tableOfContentsId?: string;\n\n // Means the dashboard contains no linked or working filters\n isReadonly?: boolean;\n\n // Means the dashboard is being previewed by ClickView staff either in product or in curator\n isPreviewing?: boolean;\n\n // Means the parent topic for the dashboard has a status of \"Coming Soon\"\n isComingSoon?: boolean;\n\n showFollowButtonSpinner?: boolean;\n \n isViewCurrentPresentation?: boolean;\n\n // By default widgets will always be lazyloaded. We override this behaviour only in extenuating \n // circumstances, such as dynamic rendering for SEO.\n lazyLoad?: boolean;\n\n moviesAndTv?: boolean;\n\n isTeacherOnly?: boolean;\n \n contentType?: CalendarEventContentType;\n\n isBot?: boolean;\n\n settings?: AllClassificationWidgetTemplates['settings'];\n\n commonVideoProps: CommonVideoProps;\n}\n\nClassificationDashboard.defaultProps = {\n appLinks: {}\n};\n\nexport function ClassificationDashboard(props: ClassificationDashboardProps): JSX.Element {\n const { widgets, videoList, videoListWidgetId } = useGetTopicsWidgets(props.dashboard, props.activeAudiences);\n\n const isSmallScreen = useMediaQuery(MediaQueryStrings.LGDown);\n const headingRef = React.useRef<Set<Element>>(new Set());\n\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n\n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n const [ controlledId, setControlledId ] = React.useState(props.tableOfContentsId);\n\n const [ tableOfContentActiveId, setTableOfContentActiveId ] = React.useState<string>('');\n\n const headingElements = Array.from(headingRef.current);\n useTableOfContentsScroll(headingElements, controlledId);\n useTableOfContentsActiveHeading({\n setActiveId: setTableOfContentActiveId,\n headingElements,\n controlledId,\n setControlledId\n });\n\n const isHubDashboard = props.classification.type === ClassificationType.Hub;\n const isChannelTopic = !!props.dashboard?.metadata?.channelId;\n\n function shouldShowEmptyState(): boolean {\n if (props.isComingSoon)\n return false;\n\n if (props.isTeacherOnly)\n return false;\n\n if (!props.dashboard)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Archived && !props.isReadonly)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Draft && !props.isPreviewing)\n return true;\n\n if (!widgets?.length)\n return true;\n\n if (videoList && videoList.length)\n return false;\n\n return Object.values(emptyWidgets).every(state => !!state);\n }\n\n function getWidgetContentRequest(\n id: string,\n widgetTypeId: WidgetTypeId,\n template: WidgetTemplate,\n cursor?: string\n ): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard),\n props.activeAudiences?.map(a => a.masterId),\n props.curriculums.preferredCurriculum?.id\n );\n\n if (cursor && props.getWidgetContentRequestWithCursor)\n return props.getWidgetContentRequestWithCursor(id, params, template, cursor);\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = shouldShowEmptyState();\n\n React.useEffect(() => {\n /**\n * When we add the first widget of the dashboard, the showEmptyState is `true`, the WidgetContainer is not going to be rendered to lazyload the `content`\n * so we set the emptyWidget to initial make sure the widget container is rendered to lazyload `widget.content`\n * and let the WidgetContainer to re-set the empty state based on the actual `widget.content` from backend\n */\n if (showEmptyState) {\n setEmptyWidgets(initialEmptyWidgets);\n }\n }, [widgets?.length]);\n\n const onSetIsEmpty = React.useCallback((widgetId: string, isEmpty: boolean) => {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n // The logic beneath this if-block doesn't apply to classification directories. This is because\n // classification directories don't support audience filtering, so widgets should never be empty,\n // meaning headings should never be hidden.\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.ClassificationDirectory)) {\n setEmptyWidgets(newEmptyState);\n return;\n }\n\n let index = 0;\n\n /**\n * Every time a widget is identified as empty, we check each heading blurb widget\n * to see if it should be hidden. This will be the case when all widgets beneath a heading\n * (up until the next heading) are empty.\n */\n while (index < widgets.length) {\n const currentWidget = widgets[index];\n\n if (!isHeadingWidget(currentWidget)) {\n index++;\n continue;\n }\n\n let isHeadingEmpty = true;\n let subWidgetIndex = index + 1;\n\n while (isHeadingEmpty && subWidgetIndex < widgets.length) {\n const headingSubWidget = widgets[subWidgetIndex];\n\n if (isHeadingWidget(headingSubWidget))\n break;\n\n if (!newEmptyState[headingSubWidget.id] && !isTopicWidget(headingSubWidget))\n isHeadingEmpty = false;\n\n subWidgetIndex++;\n }\n\n index = subWidgetIndex;\n\n newEmptyState[currentWidget.id] = isHeadingEmpty;\n }\n\n setEmptyWidgets(newEmptyState);\n }, [ emptyWidgets, widgets ]);\n\n function hideWidget(widget: CuratedWidget): boolean {\n return isHeadingWidget(widget) && emptyWidgets[widget.id];\n }\n\n function useLargeDashboardSpacing(): boolean {\n const target = CuratedDashboardHelper.getDashboardTargetType(props.dashboard);\n\n if (props.moviesAndTv || target === DashboardTargetType.ClassificationCurriculum)\n return false;\n\n return true;\n }\n\n function getWidgetHeading(widget: CuratedWidget, index: number): string {\n if (widget.widgetId === WidgetTypeId.ClassificationDashboardExternalMedia) {\n const previousWidget = widgets[index - 1];\n\n if (emptyWidgets[previousWidget.id])\n return widget.name.replace('Other videos', 'Videos');\n\n return widget.name;\n }\n\n return widget.name;\n }\n\n const widgetsInTableOfContents = widgets.filter(w => {\n return !hideWidget(w) && !!w.metadata?.showInTableOfContents;\n });\n\n const isTopicOnlyDashboard = widgets.every(isTopicWidget);\n\n const shouldShowTableOfContents = widgetsInTableOfContents.length >= 2;\n const shouldShowSideTableOfContents = shouldShowTableOfContents && !isSmallScreen;\n\n const shouldShowTopicCounts = (\n props.settings?.hasTopicDirectories &&\n TopicsHelper.isTopLevelTopic(props.classification) &&\n !props.isTertiaryCustomerWithoutExchange &&\n !isHubDashboard\n );\n\n /**\n * We don't put the .topic-dashboard class when we're in a movies and tv classification\n * because we don't want the extra padding between widgets.\n */\n return (\n <div className={`bg-white px-4 ${useLargeDashboardSpacing() ? 'dashboard-spacing-lg' : ''}`}>\n\n <BannerHeader\n type={isChannelTopic ? 'channel-topic' : 'default'}\n logo={isChannelTopic && props.channel?._logo.value}\n logoBgColour={isChannelTopic && props.channel?._colour.value}\n heading={props.classification.name}\n banner={props.classification.banner}\n imageCdnUrl={props.imageCdnUrl}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n specialEvent={props.specialEvent}\n calendarTheme={{\n background: 'bg-light-blue',\n border: 'border-light-blue'\n }}\n showComingSoon={props.isComingSoon}\n detailsComponent={shouldShowTopicCounts ?\n () => <ClassificationHeaderDetails classification={props.classification} /> :\n null\n }\n />\n\n {!isHubDashboard ? (\n <ClassificationDashboardNav\n forceHideAudiences={isChannelTopic}\n dashboard={props.dashboard}\n classification={props.classification}\n presentation={props.presentation}\n appLinks={props.appLinks}\n activeTab={props.tab}\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n getBreadcrumbs={props.getBreadcrumbs}\n hasTopicDirectoryDashboard={props.hasTopicDirectoryDashboard}\n hasTopicCurriculumDashboard={props.hasTopicCurriculumDashboard}\n isComingSoon={props.isComingSoon}\n isEmpty={showEmptyState}\n isViewingCurrentPresentation={props.isViewCurrentPresentation}\n disableAudiences={isTopicOnlyDashboard || props.isReadonly}\n audienceTooltip={isTopicOnlyDashboard ? LanguageService.getPhrase(namespace, 'audienceTooltip') : ''}\n />\n ) : (\n <div className='py-3 mb-3 border-bottom'>\n <div className='mt-3'>\n <ExpandableTextInline>\n {() => (\n <p className='mb-0'>{props.classification.description}</p>\n )}\n </ExpandableTextInline>\n </div>\n </div>\n )}\n\n {props.isComingSoon && (\n <ClassificationComingSoon\n imageUrl={props.comingSoonImageUrl}\n data={props.classification}\n canFollowSubjects={props.canFollowSubjects}\n showFollowButtonSpinner={props.showFollowButtonSpinner}\n onToggleFollow={() => props.onToggleFollow(props.classification, LocationContext.ClassificationComingSoon)}\n showSignUp={!props.hasLocalPermissions(LocalPermissionName.FollowComingSoonTopics)}\n signUpAppLink={props.appLinks.signUp?.()}\n />\n )}\n\n {!props.isComingSoon && (\n <div className={`${shouldShowSideTableOfContents ? 'row no-wrap' : ''}`}>\n {shouldShowTableOfContents && (\n <TableOfContentsContainer\n widgets={widgetsInTableOfContents}\n title={props.classification.name}\n activeId={tableOfContentActiveId}\n clickable={!props.isReadonly}\n analyticsData={props.analyticsData}\n setControlledId={setControlledId}\n isSmallScreen={isSmallScreen}\n />\n )}\n\n <div className={shouldShowSideTableOfContents ? 'col-9 order-0' : ''}>\n {widgets.map((widget, idx) => {\n if (hideWidget(widget))\n return <React.Fragment key={widget.id}></React.Fragment>;\n\n if (InfiniteFetchWidgetIds.includes(widget.widgetId)) {\n return (\n <InfiniteWidgetContainerView<CuratedWidget, CuratedWidget, AllClassificationWidgetTemplates>\n index={idx}\n key={widget.id}\n item={widget}\n infiniteFetch={shouldInfiniteFetch(widgets, idx) && !!props.getWidgetContentRequestWithCursor}\n dashboardTarget={CuratedDashboardHelper.getDashboardTargetType(props.dashboard)}\n\n getName={w => getWidgetHeading(w, idx)}\n getWidgetMetadata={w => w.metadata}\n getContent={w => w.content}\n getCursor={w => w.cursor}\n getRequest={cursor => (\n getWidgetContentRequest(widget.id, widget.widgetId, widget.templateId, cursor)\n )}\n isEmptyPredicate={isWidgetContentEmpty}\n\n audiences={props.audiences}\n appLinks={props.appLinks}\n commonVideoProps={props.commonVideoProps}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n resultsTransformers={WidgetHelper.getWidgetResultsTransformers()}\n\n presentation={props.presentation}\n analyticsData={props.analyticsData}\n imageCdnUrl={props.imageCdnUrl}\n imageUrls={props.imageUrls}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n lazyLoad={props.lazyLoad}\n\n headingElementRef={headingRef}\n hasTableOfContents={shouldShowSideTableOfContents}\n isScrollToTargetWidget={props.scrollToWidgetId === widget.id}\n isBot={props.isBot}\n isPreviewing={props.isReadonly}\n isEditing={props.isReadonly}\n curriculums={props.curriculums}\n contentType={props.contentType}\n\n setIsEmpty={isEmpty => onSetIsEmpty(widget.id, isEmpty)}\n\n getSelectedItems={null}\n appLinkOptions={null}\n />\n );\n }\n\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Classification}\n headingElementRef={headingRef}\n key={widget.id}\n id={widget.id}\n name={getWidgetHeading(widget, idx)}\n description={widget.description}\n classification={props.classification}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n audiences={props.audiences}\n getContentRequest={getWidgetContentRequest}\n setIsEmpty={onSetIsEmpty}\n appLinks={props.appLinks}\n presentation={props.presentation}\n analyticsData={props.analyticsData}\n isScrollToTargetWidget={props.scrollToWidgetId === widget.id}\n imageCdnUrl={props.imageCdnUrl}\n imageUrls={props.imageUrls}\n onSubmitFeedback={props.onSubmitFeedback}\n onDownloadAllClick={props.onDownloadAllClick}\n metadata={widget.metadata}\n isBot={props.isBot}\n hasTableOfContents={shouldShowSideTableOfContents}\n lazyLoad={props.lazyLoad}\n dashboardTarget={CuratedDashboardHelper.getDashboardTargetType(props.dashboard)}\n widgetIndex={idx}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n contentType={props.contentType}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n onToggleFollowClassification={props.onToggleFollow}\n settings={props.settings}\n isEditing={props.isReadonly}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n commonVideoProps={props.commonVideoProps}\n curriculums={props.curriculums}\n\n // TODO: Do we actually need this shit if it wasn't even being passed in?\n limitTotalItems={false}\n seeMoreLink={null}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n </div>\n\n {!!videoList?.length && (\n <>\n <WidgetHeader name={LanguageService.getPhrase(namespace, 'videos')} />\n <VideoList\n videos={videoList}\n getVideoAppLink={(video, opts) => props.appLinks.videoType(\n video,\n { ...opts, contextId: videoListWidgetId, includeContext: opts.includeContext }\n )}\n hasPermissions={props.hasPermissions}\n presentationAudiences={props.audiences}\n getPreviewQuestionsAppLink={props.appLinks.previewQuestions}\n commonVideoProps={props.commonVideoProps}\n />\n </>\n )}\n </div>\n )}\n\n {showEmptyState && (\n <CuratedClassificationEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.appLinks.widgetWizard}\n />\n )}\n\n {props.isTeacherOnly && (\n <TeacherOnlyEmptyState\n imageUrl={props.emptyImageUrl}\n ctaAppLink={() => props.appLinks.allTopics(props.classification.presentationId)}\n />\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { ContentPartnerDashboard } from 'libs/shared/apps/content-partners/components/content-partner-dashboard/ContentPartnerDashboard';\nimport { DiscoverDashboard } from 'libs/shared/apps/discover/components/discover-dashboard/DiscoverDashboard';\nimport { CompanyDashboard } from 'libs/shared/apps/movies-and-tv/components/company-dashboard/CompanyDashboard';\nimport { MoviesAndTvDashboard } from 'libs/shared/apps/movies-and-tv/components/movies-and-tv-dashboard/MoviesAndTvDashboard';\nimport { StreamableCompanyDashboard } from 'libs/shared/apps/streamable-learning/components/company-dashboard/StreamableCompanyDashboard';\nimport { StreamableDiscoverDashboard } from 'libs/shared/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard';\nimport { ClassificationDashboard } from 'libs/shared/apps/subjects/components/classification-dashboard/ClassificationDashboard';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { BannerPortalContextProvider } from 'libs/shared/context/BannerPortalContext';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { CalendarEventContentType, Classification, Company, CuratedDashboard, CuratedWidgetData, CuratedWidgetQueryParams, DashboardStatus, DashboardTargetType, PartnerProfile, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { DialogHelper } from 'libs/shared/utils/DialogHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { DashboardWidgetImageUrls } from 'shared/constants/DashboardWidgetImageUrls';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\nimport { MockHasPermissions } from 'shared/utils/MockHasPermissions';\n\nimport { useMockCurriculums } from 'apps/curriculums/hooks/useMockCurriculums';\nimport { CURATOR_HARD_CODED_SETTINGS } from 'apps/dashboard-editor/constants/CuratorHardCodedSettings';\nimport { DashboardEditorHelper } from 'apps/dashboard-editor/utils/DashboardEditorHelper';\n\nconst BANNER_CONTAINER_CLASS_NAME = 'banner-portal-container';\n\ninterface DashboardEditorPreviewProps {\n dashboard: CuratedDashboard<CuratedWidgetData>;\n presentation?: Presentation;\n cvLivePresentation?: Presentation;\n availablePresentations?: Presentation[];\n classification?: Classification;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation?: Presentation,\n cursor?: string\n ) => Flight.Request;\n getBreadcrumbs?: () => Breadcrumb[];\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n scrollToWidgetId?: string;\n moviesAndTvIconUrl?: string;\n company?: Company;\n commonVideoProps: CommonVideoProps;\n partnerProfile?: PartnerProfile;\n onClickSearchAllVideos?: () => void;\n}\n\nexport function DashboardEditorPreview(props: DashboardEditorPreviewProps): JSX.Element {\n const curriculums = useMockCurriculums();\n\n React.useEffect(() => {\n if (DashboardHelper.canEdit(props.dashboard))\n return;\n\n const isPublished = props.dashboard.status === DashboardStatus.Published;\n\n const message = isPublished ?\n 'Published dashboards can\\'t be edited.' :\n 'Archived dashboards can\\'t be edited.';\n\n DialogHelper.render(\n <div>\n <p>{message}</p>\n\n {isPublished && (\n <p>If you would like to make some changes, please create a copy of this dashboard.</p>\n )}\n </div>,\n {\n title: 'This dashboard can\\'t be edited',\n submitButtonProps: {\n text: 'Okay',\n variant: 'dark'\n }\n }\n );\n }, []);\n\n function mockOnSubmitFeedback(): Promise<void> {\n return new Promise(resolve => {\n window.setTimeout(() => {\n resolve();\n }, 300);\n });\n }\n\n const isStreamableProduct = DashboardHelper.isProduct(\n props.dashboard,\n ProductId.StreamableLearning,\n props.cvLivePresentation?.id\n );\n\n if (CuratedDashboardHelper.isClassificationDashboard(\n CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard)\n )) {\n const targetType = CuratedDashboardHelper.getDashboardTargetType(props.dashboard);\n\n return (\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <div className={BANNER_CONTAINER_CLASS_NAME} />\n <div className='container px-4'>\n <ClassificationDashboard\n getWidgetContentRequest={props.getWidgetContentRequest}\n dashboard={props.dashboard}\n classification={props.classification}\n getBreadcrumbs={props.getBreadcrumbs}\n audiences={props.audiences}\n presentation={props.presentation}\n imageCdnUrl={ClickView.Config.Urls.ImageAPI}\n resourceThumbnailFallbackImageUrl={null}\n emptyImageUrl={props.emptyImageUrl}\n imageUrls={DashboardWidgetImageUrls}\n appLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n onSubmitFeedback={mockOnSubmitFeedback}\n isBot={false}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isPreviewing\n isReadonly\n canFollowSubjects\n scrollToWidgetId={props.scrollToWidgetId}\n settings={CURATOR_HARD_CODED_SETTINGS}\n contentType={props.classification?.presentationId === props.cvLivePresentation?.id &&\n CalendarEventContentType.Livestream\n }\n onDownloadAllClick={() => {}}\n hasTopicDirectoryDashboard\n tab={TopicsHelper.getActiveTopicTab(props.classification, targetType)}\n hasTopicCurriculumDashboard={true}\n isTertiaryCustomerWithoutExchange={false}\n commonVideoProps={props.commonVideoProps}\n curriculums={curriculums}\n />\n </div>\n </BannerPortalContextProvider>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.Discover)) {\n if (isStreamableProduct) {\n return (\n <div className='container px-4'>\n <StreamableDiscoverDashboard\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n audiences={props.audiences}\n isReadonly\n commonVideoProps={props.commonVideoProps}\n />\n </div>\n );\n }\n\n return (\n <div className='container px-4'>\n <DiscoverDashboard\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n audiences={props.audiences}\n onSubmitFeedback={mockOnSubmitFeedback}\n removeFromVideoHistory={Promise.resolve}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n settings={CURATOR_HARD_CODED_SETTINGS}\n isReadonly\n commonVideoProps={props.commonVideoProps}\n\n // always show calendar header for preview in curation studio\n showCalendar\n availablePresentations={props.availablePresentations}\n isTertiaryCustomerWithoutExchange={false}\n />\n </div>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.MoviesAndTv)) {\n return (\n <div className='container px-4'>\n <MoviesAndTvDashboard\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isReadonly\n showPreviewingTooltip\n moviesAndTvIconUrl={props.moviesAndTvIconUrl}\n products={{\n hasProduct: () => true,\n isLoadingProducts: false,\n products: null\n }}\n commonVideoProps={props.commonVideoProps}\n settings={CURATOR_HARD_CODED_SETTINGS}\n />\n </div>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.Company)) {\n if (isStreamableProduct) {\n return (\n <div className='container px-4'>\n <StreamableCompanyDashboard\n dashboard={props.dashboard}\n company={props.company}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isReadOnly\n getBreadcrumbs={props.getBreadcrumbs}\n commonVideoProps={props.commonVideoProps}\n />\n </div>\n );\n }\n return (\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <div className={BANNER_CONTAINER_CLASS_NAME} />\n <div className='container px-4'>\n <CompanyDashboard\n dashboard={props.dashboard}\n company={props.company}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isReadonly\n getBreadcrumbs={props.getBreadcrumbs}\n commonVideoProps={props.commonVideoProps}\n />\n </div>\n </BannerPortalContextProvider>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.PartnerProfile)) {\n return (\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <div className={BANNER_CONTAINER_CLASS_NAME} />\n <div className='container px-4'>\n <ContentPartnerDashboard\n partnerProfile={props.partnerProfile}\n isInContentRegion\n isAuthenticated\n onClickSignUp={null}\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n breadcrumbs={props.getBreadcrumbs?.()}\n emptyImageUrl={props.emptyImageUrl}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n commonVideoProps={props.commonVideoProps}\n isPreviewing\n settings={CURATOR_HARD_CODED_SETTINGS}\n onClickSearchAllVideos={props.onClickSearchAllVideos}\n />\n </div>\n </BannerPortalContextProvider>\n );\n }\n return <></>;\n}\n",":local {\n .badge {\n gap: map-get($spacers, 1);\n padding-right: 1rem;\n\n &.draftLight {\n color: $gray-800;\n border: 0.0625rem solid $gray-800;\n background-color: rgba($gray-800, 0.05);\n }\n\n &.draftDark {\n color: $gray-300;\n border: 0.0625rem solid $gray-300;\n background-color: rgba($gray-300, 0.05);\n }\n\n &.published {\n color: $success;\n border: 0.0625rem solid $success;\n background-color: rgba($success, 0.05);\n }\n\n &.archived {\n color: $danger;\n border: 0.0625rem solid $danger;\n background-color: rgba($danger, 0.05);\n }\n }\n}","import React from 'react';\n\nimport { DashboardStatusConfig } from 'libs/shared/apps/subjects/constants/DashboardStatusConfig';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { DashboardStatus } from 'libs/shared/interfaces';\n\nimport styles from './dashboard-status-badge.module.scss';\n\nfunction getClassName(props: DashboardStatusBadgeProps): string {\n let className = `rounded-pill d-flex align-items-center ps-2 py-1 fw-semibold ms-2 ${styles.badge}`;\n\n switch (props.status) {\n case DashboardStatus.Published:\n className += ` ${styles.published}`;\n break;\n case DashboardStatus.Archived:\n className += ` ${styles.archived}`;\n break;\n case DashboardStatus.Draft:\n className += ` ${props.darkMode ? styles.draftDark : styles.draftLight}`;\n break;\n }\n\n if (props.wrapperClassName)\n className += ` ${props.wrapperClassName}`;\n\n return className;\n}\n\ninterface DashboardStatusBadgeProps {\n status: DashboardStatus;\n darkMode?: boolean;\n wrapperClassName?: string;\n}\n\nexport function DashboardStatusBadge(props: DashboardStatusBadgeProps): JSX.Element {\n const { statusName, svg } = DashboardStatusConfig[props.status];\n\n return (\n <div className={getClassName(props)}>\n <SvgContainer svg={svg} />\n <div>{statusName}</div>\n </div>\n );\n}\n",":local {\n .sticky {\n position: sticky;\n top: 0;\n z-index: 3;\n }\n}","import React from 'react';\n\nimport { DashboardStatusBadge } from 'libs/shared/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { CuratedDashboard, Presentation } from 'libs/shared/interfaces';\n\nimport styles from './dashboard-sticky-header.module.scss';\n\ninterface DashboardStickyHeaderProps {\n presentation?: Presentation;\n dashboard: CuratedDashboard;\n isSaving: boolean;\n getActions: () => ActionOptions[];\n}\n\nexport function DashboardStickyHeader(props: DashboardStickyHeaderProps): JSX.Element {\n return (\n <div className={`bg-white border-bottom ${styles.sticky}`}>\n <div className='d-flex justify-content-between align-items-center'>\n <div className='d-flex align-items-center'>\n <DashboardStatusBadge status={props.dashboard?.status} />\n\n <div className='d-flex flex-column ms-2'>\n <h2 className='font-size-normal mb-0'>\n {props.presentation?.description ? `[${props.presentation?.description}]` : ''} {props.dashboard?.name}\n </h2>\n <small className='text-secondary'>\n {props.isSaving ? 'Saving...' : 'Saved'}\n </small>\n </div>\n </div>\n\n <div className='p-2'>\n <Actions className='justify-content-end' actions={props.getActions()} />\n </div>\n </div>\n </div>\n );\n}\n",":local {\n $top-nav-height: 3rem;\n $loader-size: 5rem;\n\n .container {\n position: absolute;\n top: $top-nav-height;\n height: 100%;\n width: 100%;\n z-index: 100;\n background-color: rgba(255, 255, 255, 0.8);\n }\n\n .content {\n width: $loader-size;\n height: $loader-size;\n }\n}","import React from 'react';\n\nimport styles from './loading-mask.module.scss';\n\nexport function LoadingMask(): JSX.Element {\n return (\n <div className={`d-flex justify-content-center align-items-center ${styles.container}`}>\n <div className={`${styles.content} spinner-border`} role='status'>\n <span className='visually-hidden'>Loading...</span>\n </div>\n </div>\n );\n}\n",":local {\n $gap: 2.063rem;\n\n .indicator {\n border-top: 0.125rem solid $blue;\n left: 0;\n position: absolute;\n }\n\n .above {\n top: -$gap;\n }\n\n .below {\n bottom: -$gap;\n }\n}","import React from 'react';\n\nimport styles from './drop-indicator.module.scss';\n\ninterface DropIndicatorProps {\n dragDirection: 'up' | 'down';\n}\n\nexport function DropIndicator(props: DropIndicatorProps) {\n if (!props.dragDirection) {\n return null;\n }\n\n const position = props.dragDirection === 'up' ? styles.above : styles.below;\n\n return <hr className={`${styles.indicator} ${position} visible w-100 position-absolute`} />;\n}\n","import React from 'react';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nimport { CuratorWidgetTypeIdConfig } from 'apps/dashboard-editor/constants/CuratorWidgetTypeIdConfig';\n\ninterface WidgetIconProps {\n id: WidgetTypeId;\n}\n\nexport function DashboardWidgetIcon(props: WidgetIconProps) {\n const config = CuratorWidgetTypeIdConfig[props.id];\n \n if (!config)\n return <></>;\n\n return (\n <div className={`text-white rounded ${config.bgColourClass}`}>\n <SvgContainer svg={config.icon} />\n </div>\n );\n}\n",":local {\n $item-height: 14rem;\n $number-container-size: 1rem;\n $svg-container-height: 3.5rem;\n\n .widgetNumber {\n display: block;\n }\n\n .widgetHandle {\n display: none;\n }\n\n .widgetActions {\n visibility: hidden;\n }\n\n .widgetItem {\n height: $item-height;\n \n &:hover {\n background-color: $light-blue;\n\n .widgetNumber {\n display: none;\n }\n\n .widgetHandle {\n display: block;\n }\n\n .widgetActions {\n visibility: visible;\n }\n }\n\n &.disabled {\n background-color: $gray-200;\n &:hover {\n .widgetNumber {\n display: block;\n }\n \n .widgetHandle {\n display: none;\n }\n }\n }\n }\n\n .numberContainer {\n flex-shrink: 0;\n width: $number-container-size;\n height: $number-container-size;\n }\n\n .svgContainer {\n height: $svg-container-height;\n color: $gray-400;\n }\n\n .disabledAction {\n pointer-events: all !important; // overrides bootstrap 'disabled' class\n }\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { ActionsDropdown, DropdownActionOptions } from 'libs/shared/components/actions/ActionsDropdown';\nimport { PropsWithSortableItemProps } from 'libs/shared/components/sortable/SortableItemWrapper';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { DropIndicator } from 'shared/components/drop-indicator/DropIndicator';\nimport { Actions, AppChannels } from 'shared/constants';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { DashboardWidgetIcon } from 'apps/dashboard-editor/components/dashboard-widget-icon/DashboardWidgetIcon';\n\nimport styles from './widget-editor-item.module.scss';\n\ninterface WidgetEditorItemProps extends Partial<PropsWithSortableItemProps<CuratedWidget>> {\n index: number;\n templates: CuratedWidgetTemplate[];\n dragHandleIcon: SvgIcon;\n dragHandleIconSize: SvgContainerSize;\n dashboard: CuratedDashboard;\n style?: HashObject;\n setScrollToWidgetId?: (id: string) => void;\n headingClassName?: string;\n isReadOnlyWidget?: boolean;\n}\n\nexport const WidgetEditorItem = React.forwardRef(\n (props: WidgetEditorItemProps, ref: React.LegacyRef<HTMLDivElement>) => {\n const isDisabled = !DashboardHelper.canEdit(props.dashboard) || props.isReadOnlyWidget;\n\n const preventHighlight = React.useRef(false);\n\n const toggleId = `dropdown-toggle-${props.index}`;\n\n function handleClick(e: React.MouseEvent<HTMLElement>): void {\n if (e.currentTarget.id === toggleId) {\n preventHighlight.current = true;\n return;\n }\n\n if (preventHighlight.current) {\n preventHighlight.current = false;\n return;\n }\n\n props.setScrollToWidgetId?.(props.id);\n }\n\n function getActions(): DropdownActionOptions[] {\n if (!DashboardHelper.canEdit(props.dashboard))\n return [];\n\n const disableDelete = (\n props.dashboard.status === DashboardStatus.Published &&\n props.dashboard.widgets.length === 1\n );\n\n const deleteAction: DropdownActionOptions = {\n label: 'Delete',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.DELETE_WIDGET,\n args: [props.id]\n },\n className: `btn btn-link text-danger ${disableDelete ? `disabled cursor-default ${styles.disabledAction}` : ''}`,\n disabled: disableDelete,\n tooltip: disableDelete ? 'Published dashboards must have at least 1 widget' : ''\n };\n\n if (props.isReadOnlyWidget)\n return [deleteAction];\n\n return [\n {\n label: 'Edit content',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.WIZARD_EDIT_CONTENT,\n args: [ props.dashboardId, props.id, props.widgetId, props.templateId ]\n },\n className: 'btn btn-link'\n },\n deleteAction\n ];\n }\n\n const templateName = WidgetTemplateConfig[props.templateId].displayName ??\n props.templates?.find(t => t.id === props.templateId).name;\n\n return (\n <div\n className={`p-3 me-1 border border-secondary rounded-3 ${isDisabled ? 'cursor-default' : 'cursor-grab'} ${isDisabled ? styles.disabled : ''} ${styles.widgetItem}`}\n onClick={handleClick}\n style={props.style}\n ref={ref}\n aria-roledescription='Sortable widget'\n {...props.dragAttributes}\n {...props.dragListeners}\n >\n <DropIndicator dragDirection={props.dragDirection} />\n <div className='d-flex justify-content-between w-100'>\n <div className='d-flex'>\n <div className={styles.numberContainer}>\n <div className={`${styles.widgetNumber} mx-auto text-center h6`}>\n <strong>{props.index + 1}</strong>\n </div>\n <SvgContainer\n svg={props.dragHandleIcon}\n size={props.dragHandleIconSize}\n className={styles.widgetHandle}\n />\n </div>\n <div className='ps-2'>\n <DashboardWidgetIcon id={props.widgetId} />\n </div>\n <div className='ps-2 fw-semibold'>{templateName}</div>\n </div>\n <div id={toggleId} className={styles.widgetActions} onClick={handleClick}>\n <ActionsDropdown actions={getActions()} dropdownToggleClassName='border-0 bg-transparent' />\n </div>\n </div>\n <div className={`pt-2 clamp-2 ${props.headingClassName || ''}`} title={props.name}><strong>{props.name}</strong></div>\n <div className='pt-2'>\n <SvgContainer className={`${styles.svgContainer}`} svg={WidgetTemplateConfig[props.templateId].icon} />\n </div>\n </div>\n );\n }\n);\n",":local {\n $top-nav-height: 2.5rem;\n $footer-height: 30px;\n\n .itemListWrapper {\n height: calc(100vh - (#{$top-nav-height} + #{$footer-height}));\n }\n\n .header {\n position: sticky;\n top: 0;\n z-index: 3;\n }\n}","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport { DragEndEvent } from '@dnd-kit/core';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SortableContainerWrapper } from 'libs/shared/components/sortable/SortableContainerWrapper';\nimport { SortableItemWrapper } from 'libs/shared/components/sortable/SortableItemWrapper';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { DragOverlayStyles } from 'libs/shared/constants/DragOverlayStyles';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { WidgetEditorItem } from 'apps/dashboard-editor/components/widget-editor-item/WidgetEditorItem';\n\nimport styles from './widget-editor-list.module.scss';\n\nexport interface WidgetEditorListProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n templates: CuratedWidgetTemplate[];\n startingPositionIndex?: number;\n}\n\ninterface SortableWidgetEditorListProps extends WidgetEditorListProps {\n dragHandleIcon: SvgIcon;\n dragHandleIconSize: SvgContainerSize;\n onSortEnd: (event: DragEndEvent) => void;\n currentSortingIndex?: number;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function SortableWidgetEditorList(props: SortableWidgetEditorListProps): JSX.Element {\n function getDragOverlay(id: string) {\n const widgetIndex = props.widgets.findIndex(widget => widget.id === id);\n const widget = props.widgets[widgetIndex];\n\n return (\n <WidgetEditorItem\n index={widgetIndex}\n templates={props.templates}\n dragHandleIcon={props.dragHandleIcon}\n dragHandleIconSize={props.dragHandleIconSize}\n style={DragOverlayStyles}\n setScrollToWidgetId={props.setScrollToWidget}\n dashboard={props.dashboard}\n {...widget}\n />\n );\n }\n\n function getCreateTooltip(): string {\n if (props.dashboard.status === DashboardStatus.Archived)\n return 'Archived dashboards cannot be edited';\n\n if (props.dashboard.status === DashboardStatus.Published)\n return 'Published dashboards cannot be edited. Please create a copy to make any changes.';\n\n return '';\n }\n\n const isDisabled = !DashboardHelper.canEdit(props.dashboard);\n\n return (\n <div className='position-relative'>\n <div className={`bg-white border-bottom ${styles.header}`}>\n <div className='d-flex justify-content-between align-items-center p-2 me-1'>\n <h2 className='h5 mb-0'>Content</h2>\n <Tooltip title={getCreateTooltip()} placement='right' spanHack>\n <IconButton\n className='btn btn-dark'\n svg={PlusSvg}\n appLink={{\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.WIZARD_SELECT_WIDGET,\n args: [props.dashboard.id]\n }}\n disabled={isDisabled}\n />\n </Tooltip>\n </div>\n </div>\n\n <SortableContainerWrapper\n ids={props.widgets.map(w => w.id)}\n getDragOverlay={getDragOverlay}\n onSortEnd={props.onSortEnd}\n dropAnimation={{ duration: 100 }}\n disabled={isDisabled}\n >\n <div className={`${styles.itemListWrapper}`}>\n <Scrollbars>\n <ol className='list-unstyled px-2 pb-2 mb-0'>\n {props.widgets.filter(w => WidgetTemplateConfig[w.templateId]).map((widget, idx) => {\n let heading = widget.name || '';\n let headingClassName = '';\n\n if (!heading) {\n heading = 'No heading';\n headingClassName = 'fst-italic';\n }\n\n const isReadOnlyWidget = DashboardHelper.isWidgetReadonly(widget);\n\n return (\n <li className='pb-3' key={widget.id}>\n <SortableItemWrapper\n id={widget.id}\n disabled={isReadOnlyWidget}\n childComponent={WidgetEditorItem}\n childProps={{\n ...widget,\n name: heading,\n headingClassName,\n index: idx,\n templates: props.templates,\n dragHandleIcon: props.dragHandleIcon,\n dragHandleIconSize: props.dragHandleIconSize,\n setScrollToWidgetId: props.setScrollToWidget,\n dashboard: props.dashboard,\n isReadOnlyWidget\n }}\n />\n </li>\n );\n })}\n </ol>\n </Scrollbars>\n </div>\n </SortableContainerWrapper>\n \n </div>\n );\n}\n","import React from 'react';\nimport { DragEndEvent } from '@dnd-kit/core';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { HandleSvg } from 'libs/shared/images/svg/objects/HandleSvg';\n\nimport { SortableWidgetEditorList, WidgetEditorListProps } from 'apps/dashboard-editor/components/widget-editor-list/WidgetEditorList';\n\ninterface SortableWidgetEditorListContainerProps extends WidgetEditorListProps {\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function SortableWidgetEditorListContainer(props: SortableWidgetEditorListContainerProps): React.ReactElement {\n const { onSortComplete, ...widgetListProps } = props;\n\n const onSortEnd = (event: DragEndEvent) => {\n const oldIndex = ArrayHelper.findMatchedIdIndex(props.widgets, event.active.id);\n const newIndex = ArrayHelper.findMatchedIdIndex(props.widgets, event.over.id);\n\n onSortComplete(oldIndex, newIndex);\n };\n\n return (\n <SortableWidgetEditorList\n {...widgetListProps}\n onSortEnd={onSortEnd}\n dragHandleIcon={HandleSvg}\n dragHandleIconSize={SvgContainerSize.ExtraSmall}\n setScrollToWidget={props.setScrollToWidget}\n />\n );\n}\n",":local {\n $top-nav-height: 2.5rem;\n $footer-height: 30px;\n $editor-list-width: 16rem;\n\n .contentWrapper {\n max-height: calc(100vh - (#{$top-nav-height} + #{$footer-height}));\n }\n\n .scrollbarTrack {\n position: absolute; \n width: 0.375rem; \n right: 0.125rem; \n bottom: 0.125rem; \n top: 0.125rem;\n border-radius: 0.1875rem; \n z-index: 5;\n }\n\n .widgetEditorListColumn {\n width: $editor-list-width;\n min-height: calc(100vh - #{$top-nav-height});\n position: absolute;\n left: 0;\n top: $top-nav-height;\n }\n\n .dashboardEditorPreview {\n margin-left: $editor-list-width;\n min-height: calc(100vh - (#{$top-nav-height} + #{$footer-height}));\n }\n}","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { Classification, CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\n\nimport { PresentationRequests } from 'apps/cv-live/flight-requests/CvLivePresentationRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\nconst namespace = 'dashboardEditor.editClassificationDashboardView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface EditClassificationDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditClassificationDashboardView(props: EditClassificationDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n let classificationId: string;\n if (CuratedDashboardHelper.isClassificationDashboard(targetInfo))\n classificationId = targetInfo.classificationId;\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const classification = Flight.useBasicFetch<Classification>(classificationId &&\n SubjectRequests.classification(classificationId));\n\n const presentation = Flight.useBasicFetch<Presentation>(\n classification.hasCompleted &&\n SubjectRequests.presentation(classification.data.presentationId)\n );\n\n const cvLivePresentation = Flight.useBasicFetch<Presentation>(\n PresentationRequests.cvLivePresentation()\n );\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n presentation.hasCompleted &&\n AudienceRequests.audiencesByPresentationId(presentation.data?.id)\n );\n\n const availablePresentations = Flight.useBasicFetch<Presentation[]>(\n ClassificationRequests.availablePresentations(PresentationType.Subject)\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n\n const path = Flight.useBasicFetch<Classification[]>(\n classificationId && ClassificationRequests.path(classificationId)\n );\n const isStreamable = +presentation.data?.id === +cvLivePresentation.data?.id;\n\n function getBreadcrumbs(): Breadcrumb[] {\n const breadcrumbs: Breadcrumb[] = [{\n name: getPhrase('discover')\n }, {\n name: TopicsHelper.getExploreAllTopicsBreadcrumb(presentation.data?.name, availablePresentations.data?.length)\n }];\n\n path.data.forEach(item => {\n breadcrumbs.push({\n name: item.name,\n active: item.name === classification.data.name\n });\n });\n\n return breadcrumbs;\n }\n\n function getPreviewUrl(): string {\n let baseUrl = '';\n if (isStreamable) {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.StreamableUrl,\n `topics/${classification.data.id}/${TextHelper.slugify(classification.data.name)}`\n );\n } else {\n const isDirectory = CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.ClassificationDirectory);\n\n if (isDirectory) {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `topics/${classification.data.id}/${TextHelper.slugify(classification.data.name)}/topics`\n );\n } else {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `topics/${classification.data.id}/${TextHelper.slugify(classification.data.name)}`\n );\n }\n }\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getCloseAppLink(): Core.AppLink {\n if (isStreamable) {\n return {\n application: AppChannels.CV_LIVE,\n action: Actions.CvLive.EDIT_CLASSIFICATION_DASHBOARDS,\n args: [ presentation.data.id, classification.data.id ]\n };\n }\n\n return CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.Classification) ?\n {\n application: AppChannels.SUBJECTS,\n action: Actions.Subjects.EDIT_CLASSIFICATION_DASHBOARDS,\n args: [ presentation.data.id, classification.data.id ]\n } : {\n application: AppChannels.SUBJECTS,\n action: Actions.Subjects.EDIT_CLASSIFICATION_DIRECTORIES,\n args: [ presentation.data.id, classification.data.id ]\n };\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: getCloseAppLink(),\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n availablePresentations.data &&\n classification.data &&\n path.data &&\n presentation.data &&\n curriculum.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n classification={classification.data}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n getBreadcrumbs={getBreadcrumbs}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.TOPIC_DASHBOARD}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n cvLivePresentation={cvLivePresentation.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { Company, CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { CompanyRequests } from 'apps/companies/flight-requests';\nimport { PresentationRequests } from 'apps/cv-live/flight-requests/CvLivePresentationRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditCompanyDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditCompanyDashboardView(props: EditCompanyDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n let companyId: string;\n let presentationId: string;\n\n if (targetInfo.targetType === DashboardTargetType.Company) {\n companyId = targetInfo.companyId;\n presentationId = targetInfo.presentationId;\n }\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n AudienceRequests.audiencesByPresentationId(presentationId)\n );\n\n const presentation = Flight.useBasicFetch<Presentation>(\n SubjectRequests.presentation(presentationId)\n );\n\n const cvLivePresentation = Flight.useBasicFetch<Presentation>(\n PresentationRequests.cvLivePresentation()\n );\n\n const company = Flight.useBasicFetch<Company>(\n CompanyRequests.getCompany(companyId)\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n const isStreamable = DashboardHelper.isProduct(\n props.dashboard,\n ProductId.StreamableLearning,\n cvLivePresentation.data?.id\n );\n\n function getPreviewUrl(): string {\n let baseUrl = '';\n if (isStreamable) {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.StreamableUrl,\n `/partners/${companyId}/${TextHelper.slugify(company.data.name)}`\n );\n } else {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `/studios/${companyId}/${TextHelper.slugify(company.data.name)}`\n );\n }\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n presentationId: presentation.data?.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getBreadcrumbs(): Breadcrumb[] {\n if (!company.hasCompleted)\n return [];\n\n return [{\n name: isStreamable ? 'Discover' : 'Movies + TV'\n }, {\n name: company.data.name,\n active: true\n }];\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: isStreamable ? {\n application: AppChannels.CV_LIVE,\n action: Actions.CvLive.EDIT_COMPANY_DASHBOARDS,\n args: [companyId]\n } : {\n application: AppChannels.COMPANIES,\n action: Actions.Companies.EDIT_DASHBOARDS,\n args: [ companyId, presentationId ]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n presentation.data &&\n company.data &&\n curriculum.data &&\n cvLivePresentation.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n company={company.data}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.MOVIES_AND_TV_DASHBOARD}\n moviesAndTvIconUrl={ImageUrls.Dashboard.MOVIES_AND_TV_ICON}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n getBreadcrumbs={getBreadcrumbs}\n cvLivePresentation={cvLivePresentation.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, PartnerProfile } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\n\nimport { ContentPartnerRequests } from 'apps/content-partners/flight-requests/ContentPartnerRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditContentPartnerDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditContentPartnerDashboardView(props: EditContentPartnerDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n const slug = targetInfo.targetType === DashboardTargetType.PartnerProfile ?\n targetInfo.slug :\n '';\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const contentPartner = Flight.useBasicFetch<PartnerProfile>(\n ContentPartnerRequests.getContentPartnerBySlug(slug)\n );\n\n function getPreviewUrl(): string {\n if (targetInfo.targetType !== DashboardTargetType.PartnerProfile) {\n return '';\n }\n const baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `channels/${targetInfo.slug}`\n );\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getBreadcrumbs(): Breadcrumb[] {\n return [{\n name: 'Discover'\n },\n {\n name: 'Channels'\n },\n {\n name: contentPartner.data.name,\n active: true\n }];\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: {\n application: AppChannels.CONTENT_PARTNERS,\n action: Actions.ContentPartners.CONTENT_PARTNER_DASHBOARDS,\n args: [contentPartner.data.id]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n function onClickSearchAllVideos(): void {\n const baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `search`\n );\n\n LocationUtils.PageLoad(UrlHelper.urlBuilder(baseUrl, {\n scopeId: contentPartner.data.id\n }), true);\n }\n\n const dataLoaded = contentPartner.data;\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n audiences={[]}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.MOVIES_AND_TV_DASHBOARD}\n scrollToWidgetId={props.scrollToWidget}\n getBreadcrumbs={getBreadcrumbs}\n commonVideoProps={commonVideoProps}\n partnerProfile={contentPartner.data}\n onClickSearchAllVideos={onClickSearchAllVideos}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { PresentationRequests } from 'apps/cv-live/flight-requests/CvLivePresentationRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditDiscoverDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditDiscoverDashboardView(props: EditDiscoverDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n let presentationId: string;\n if (targetInfo.targetType === DashboardTargetType.Discover)\n presentationId = targetInfo.presentationId;\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n AudienceRequests.audiencesByPresentationId(presentationId)\n );\n const availablePresentations = Flight.useBasicFetch<Presentation[]>(\n ClassificationRequests.availablePresentations(PresentationType.Subject)\n );\n const presentation = Flight.useBasicFetch<Presentation>(\n SubjectRequests.presentation(presentationId)\n );\n const cvLivePresentation = Flight.useBasicFetch<Presentation>(\n PresentationRequests.cvLivePresentation()\n );\n\n const isStreamable = DashboardHelper.isProduct(\n props.dashboard,\n ProductId.StreamableLearning,\n cvLivePresentation.data?.id\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n !isStreamable && ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n\n function getPreviewUrl(): string {\n let baseUrl = '';\n if (isStreamable) {\n baseUrl = ClickView.Config.Urls.StreamableUrl;\n } else {\n baseUrl = ClickView.Config.Urls.LiteUrl;\n }\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n presentationId: presentation.data?.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: isStreamable ? {\n application: AppChannels.CV_LIVE,\n action: Actions.CvLive.DISCOVER\n } : {\n application: AppChannels.DISCOVER,\n action: Actions.Discover.PRESENTATION_DASHBOARDS,\n args: [presentationId]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n availablePresentations.data &&\n presentation.data &&\n (isStreamable || curriculum.data) &&\n cvLivePresentation.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.DISCOVER_DASHBOARD}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n cvLivePresentation={cvLivePresentation.data}\n availablePresentations={availablePresentations.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\n\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditMoviesAndTvDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditMoviesAndTvDashboardView(props: EditMoviesAndTvDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n const presentationId = targetInfo.targetType === DashboardTargetType.MoviesAndTv &&\n targetInfo.presentationId;\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n AudienceRequests.audiencesByPresentationId(presentationId)\n );\n\n const presentation = Flight.useBasicFetch<Presentation>(\n SubjectRequests.presentation(presentationId)\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n\n function getPreviewUrl(): string {\n const baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n 'movies-and-tv'\n );\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n presentationId: presentation.data?.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: {\n application: AppChannels.MOVIES_AND_TV,\n action: Actions.MoviesAndTv.MOVIES_AND_TV_DASHBOARD,\n args: [presentationId]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n presentation.data &&\n curriculum.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.MOVIES_AND_TV_DASHBOARD}\n moviesAndTvIconUrl={ImageUrls.Dashboard.MOVIES_AND_TV_ICON}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { ClassificationWithChildren, CuratedWidget, CuratedWidgetTemplate, DashboardTargetType, ParentAndChildClassificationsWidgetData } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { WidgetRequests } from 'shared/flight-requests/WidgetRequests';\n\nimport { AnimationFinishedBuffer } from 'apps/dashboard-editor/constants/AnimationConstants';\nimport { useFetchDashboard } from 'apps/dashboard-editor/hooks/useFetchDashboard';\nimport { EditClassificationDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-classification-dashboard/EditClassificationDashboardView';\nimport { EditCompanyDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-company-dashboard/EditCompanyDashboardView';\nimport { EditContentPartnerDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-content-partner-dashboard/EditContentPartnerDashboardView';\nimport { EditDiscoverDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-discover-dashboard/EditDiscoverDashboardView';\nimport { EditMoviesAndTvDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-movies-and-tv-dashboard/EditMoviesAndTvDashboardView';\n\nlet timerId: number = 0;\nconst WIDGET_HIGHLIGHT_ANIMATION_TIMER = 4500; // Animation time in ms\n\ninterface EditDashboardContainerViewProps {\n id: string;\n}\n\nexport function EditDashboardContainerView(props: EditDashboardContainerViewProps): JSX.Element {\n const [ widgets, setWidgets ] = React.useState<CuratedWidget[]>([]);\n const [ showLoadingMask, setShowLoadingMask ] = React.useState(false);\n const [ scrollToWidget, setScrollToWidget ] = React.useState('');\n\n const dashboard = useFetchDashboard(props.id);\n\n const templates = Flight.useBasicFetch<CuratedWidgetTemplate[]>(DashboardRequests.templates());\n\n const fetch = Flight.useGetFetch();\n\n useSetPageMetadata({ title: dashboard.data?.name });\n\n React.useEffect(() => {\n document.body.style.overflowY = 'hidden';\n return () => {\n document.body.style.overflowY = 'auto';\n };\n }, []);\n\n const formattedWidgets = dashboard.data?.widgets.map(w => {\n if (w.data.classifications) {\n return {\n ...w,\n data: {\n ...w.data,\n // only pass required fields: id and options\n classifications: [ObjectHelper.pick(w.data.classifications[0], [ 'id', 'options' ]) as ClassificationWithChildren]\n } as ParentAndChildClassificationsWidgetData\n };\n }\n\n return w;\n });\n\n function onSortComplete(oldIdx: number, newIdx: number): void {\n if (oldIdx === newIdx) {\n return;\n }\n \n const oldWidgets = formattedWidgets;\n if (!oldWidgets[oldIdx] || !oldWidgets[newIdx]) {\n return;\n }\n\n const reorderedWidgets = ArrayHelper.moveItem(oldWidgets, oldIdx, newIdx).map((widget, index) => ({\n ...widget,\n index\n }));\n\n setWidgets(reorderedWidgets);\n setShowLoadingMask(true);\n\n fetch(WidgetRequests.sortWidgets(\n reorderedWidgets.map(widget => ObjectHelper.omit(widget, ['content'])),\n dashboard.data,\n null,\n // Rollback when error occurs\n () => setWidgets(oldWidgets),\n () => window.setTimeout(() => setShowLoadingMask(false), AnimationFinishedBuffer)\n ));\n }\n\n React.useEffect(() => {\n if (!scrollToWidget)\n return;\n\n // Reset any existing timer in case the user clicks on more than 1 widget in a row\n if (timerId)\n window.clearTimeout(timerId);\n\n timerId = window.setTimeout(() => {\n setScrollToWidget('');\n }, WIDGET_HIGHLIGHT_ANIMATION_TIMER);\n }, [scrollToWidget]);\n\n React.useEffect(() => {\n if (!dashboard.hasCompleted)\n return;\n\n setWidgets(dashboard.data.widgets);\n }, [ dashboard.data, dashboard.hasCompleted ]);\n\n if (!dashboard.data)\n return <></>;\n\n // TODO: Properly handle errors\n if (dashboard.hasError)\n return <>Error</>;\n\n const isSaving = showLoadingMask || (dashboard.hasCompleted && dashboard.isFetching);\n\n const commonProps = {\n dashboard: dashboard.data,\n widgets: widgets,\n isSaving: isSaving,\n showLoadingMask: showLoadingMask,\n onSortComplete: onSortComplete,\n templates: templates.data,\n scrollToWidget: scrollToWidget,\n setScrollToWidget: setScrollToWidget\n };\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.Discover))\n return <EditDiscoverDashboardView {...commonProps} />;\n\n if (CuratedDashboardHelper.isClassificationDashboard(\n CuratedDashboardHelper.getDashboardTargetInfo(dashboard.data)\n )) {\n return <EditClassificationDashboardView {...commonProps} />;\n }\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.MoviesAndTv))\n return <EditMoviesAndTvDashboardView {...commonProps} />;\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.Company))\n return <EditCompanyDashboardView {...commonProps} />;\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.PartnerProfile))\n return <EditContentPartnerDashboardView {...commonProps} />;\n\n return <></>;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"9nk_zFtT.chunk.js","names":[],"sources":["../../../../../src/shared/flight-requests/WidgetRequests.ts","../../../../../../../libs/shared/src/flight-requests/AudienceRequests.ts","../../../../../../../libs/shared/src/components/back-button/BackButton.tsx","../../../../../../../libs/shared/src/context/BannerPortalContext.tsx","../../../../../../../libs/shared/src/components/banner-header/hooks/useBannerHeader.ts","../../../../../../../libs/shared/src/components/banner-header/default-banner-header/default-banner-header.module.scss","../../../../../../../libs/shared/src/components/banner-header/default-banner-header/DefaultBannerHeader.tsx","../../../../../../../libs/shared/src/components/video/Video.tsx","../../../../../../../libs/shared/src/images/svg/actions/PauseSvg.tsx","../../../../../../../libs/shared/src/images/svg/objects/LinkSvg.tsx","../../../../../../../libs/shared/src/components/banner-header/enums/VideoBannerControlOption.ts","../../../../../../../libs/shared/src/components/banner-header/utils/PartnerProfileBannerHeaderHelper.ts","../../../../../../../libs/shared/src/components/banner-header/partner-profile-banner-header/partner-profile-banner-header.module.scss","../../../../../../../libs/shared/src/components/banner-header/partner-profile-banner-header/PartnerProfileBannerHeaderContent.tsx","../../../../../../../libs/shared/src/components/banner-header/partner-profile-banner-header/PartnerProfileBannerHeader.tsx","../../../../../../../libs/shared/src/components/banner-header/BannerHeader.tsx","../../../../../../../libs/shared/src/hooks/useTransformer.tsx","../../../../../../../libs/shared/src/components/widgets/curated-widgets/hooks/useInfiniteWidgetFetch.ts","../../../../../../../libs/shared/src/components/widgets/curated-widgets/InfiniteWidgetContainerView.tsx","../../../../../../../libs/shared/src/hooks/useEmptyWidgets.ts","../../../../../../../libs/shared/src/hooks/useExpandableTextButton.ts","../../../../../../../libs/shared/src/components/expandable-text-inline/expandable-text-inline.module.scss","../../../../../../../libs/shared/src/components/expandable-text-inline/ExpandableTextInline.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/channel-dashboard-description/ChannelDashboardDescription.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-dashboard-coming-soon/ContentPartnerDashboardComingSoon.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-dashboard-content-region/ContentPartnerDashboardContentRegion.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-dashboard-no-content/ContentPartnerDashboardNoContent.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/empty-state/content-partner-empty-state/ContentPartnerEmptyState.tsx","../../../../../../../libs/shared/src/apps/content-partners/components/content-partner-dashboard/ContentPartnerDashboard.tsx","../../../../../../../libs/shared/src/apps/discover/components/header/discover-header.module.scss","../../../../../../../libs/shared/src/apps/discover/components/header/DiscoverHeader.tsx","../../../../../../../libs/shared/src/apps/discover/components/tutorial-videos/TutorialVideoWidget.tsx","../../../../../../../libs/shared/src/components/widgets/countdown/countdown.module.scss","../../../../../../../libs/shared/src/components/widgets/countdown/CountdownWidget.tsx","../../../../../../../libs/shared/src/components/widgets/countdown/CountdownContainer.tsx","../../../../../../../libs/shared/src/components/widgets/countdown/events/commonwealth-game.ts","../../../../../../../libs/shared/src/apps/discover/components/discover-dashboard/empty-state/DiscoverDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/discover/components/discover-dashboard/DiscoverDashboard.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/company-dashboard/empty-state/CompanyDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/company-dashboard/CompanyDashboard.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/exchange-and-tv-links/exchange-and-tv-links.module.scss","../../../../../../../libs/shared/src/apps/movies-and-tv/components/exchange-and-tv-links/ExchangeAndTvLinks.tsx","../../../../../../../libs/shared/src/flight-requests/ProductRequests.ts","../../../../../../../libs/shared/src/hooks/UseProducts.ts","../../../../../../../libs/shared/src/apps/movies-and-tv/components/movies-and-tv-dashboard/empty-state/MoviesAndTvDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/movies-and-tv/components/movies-and-tv-dashboard/movies-and-tv-dashboard.module.scss","../../../../../../../libs/shared/src/apps/movies-and-tv/components/movies-and-tv-dashboard/MoviesAndTvDashboard.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/company-dashboard/empty-state/StreamableCompanyDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/subjects/components/audience-item/audience-item.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/audience-item/AudienceItem.tsx","../../../../../../../libs/shared/src/apps/subjects/components/audience-filter/AudienceFilter.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/company-dashboard/StreamableCompanyDashboard.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/header/streamable-header.module.scss","../../../../../../../libs/shared/src/apps/streamable-learning/components/header/StreamableHeader.tsx","../../../../../../../libs/shared/src/hooks/usePermissions.ts","../../../../../../../libs/shared/src/apps/streamable-learning/components/dashboard/empty-state/StreamableDiscoverDashboardEmptyState.tsx","../../../../../../../libs/shared/src/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState.tsx","../../../../../../../libs/shared/src/components/table-of-contents-list/table-of-contents-list.module.scss","../../../../../../../libs/shared/src/components/table-of-contents-list/TableOfContentsList.tsx","../../../../../../../libs/shared/src/images/svg/objects/TableOfContentsSvg.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/table-of-contents.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState.tsx","../../../../../../../libs/shared/src/flight-requests/DashboardRequests.ts","../../../../../../../libs/shared/src/apps/subjects/hooks/useGetTopicsWidgets.ts","../../../../../../../libs/shared/src/hooks/useTableOfContentsActiveHeading.tsx","../../../../../../../libs/shared/src/hooks/useTableOfContentsScroll.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-coming-soon/ClassificationComingSoon.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/audiences/ClassificationDashboardAudiences.tsx","../../../../../../../libs/shared/src/apps/subjects/hooks/useDirectoryTabProductTipSwitcher.ts","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/classification-tabs.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-tabs/ClassificationTabs.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/classification-dashboard-nav/ClassificationDashboardNav.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/ClassificationDashboard.tsx","../../../../../src/apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview.tsx","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/dashboard-status-badge.module.scss","../../../../../../../libs/shared/src/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge.tsx","../../../../../src/apps/dashboard-editor/components/dashboard-sticky-header/dashboard-sticky-header.module.scss","../../../../../src/apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader.tsx","../../../../../src/apps/dashboard-editor/components/loading-mask/loading-mask.module.scss","../../../../../src/apps/dashboard-editor/components/loading-mask/LoadingMask.tsx","../../../../../src/shared/components/drop-indicator/drop-indicator.module.scss","../../../../../src/shared/components/drop-indicator/DropIndicator.tsx","../../../../../src/apps/dashboard-editor/components/dashboard-widget-icon/DashboardWidgetIcon.tsx","../../../../../src/apps/dashboard-editor/components/widget-editor-item/widget-editor-item.module.scss","../../../../../src/apps/dashboard-editor/components/widget-editor-item/WidgetEditorItem.tsx","../../../../../src/apps/dashboard-editor/components/widget-editor-list/widget-editor-list.module.scss","../../../../../src/apps/dashboard-editor/components/widget-editor-list/WidgetEditorList.tsx","../../../../../src/apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-dashboard-view.module.scss","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-classification-dashboard/EditClassificationDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-company-dashboard/EditCompanyDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-content-partner-dashboard/EditContentPartnerDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-discover-dashboard/EditDiscoverDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/edit-movies-and-tv-dashboard/EditMoviesAndTvDashboardView.tsx","../../../../../src/apps/dashboard-editor/views/edit-dashboard/EditDashboardContainerView.tsx"],"sourcesContent":["import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Flight } from 'libs/common/flight';\n\nimport { CuratedDashboard, CuratedWidget } from 'libs/shared/interfaces';\n\nexport const WidgetRequests = {\n sortWidgets(\n widgets: CuratedWidget[],\n dashboard: CuratedDashboard,\n success?: (data: CuratedWidget[]) => void,\n error?: () => void,\n always?: () => void\n ): Flight.Request {\n const dashboardKey = `dashboard:${dashboard.id}`;\n\n return {\n url: '/api/discover/v1/widgets/bulk',\n key: 'widgets:bulk',\n type: HttpVerbs.PUT,\n data: widgets,\n success,\n error,\n always,\n normalize: false,\n invalidationKeys: dashboardKey\n };\n }\n};\n","import { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\n\nexport const AudienceRequests = {\n presentationAudiences(presentationType: PresentationType, presentationId?: string): Flight.PublicRequest {\n const requestOpts = {\n type: presentationType\n };\n\n return {\n bootstrapName: 'presentationAudiences',\n url: UrlHelper.urlBuilder('{gateway}/v1/users/me/audiences', requestOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/subjects/presentation/${presentationId}/audiences`, requestOpts),\n regionScoped: true,\n key: `presentation:audiences:${presentationId}:${presentationType}`,\n normalize: false\n };\n },\n\n audiencesByPresentationId(presentationId: string): Flight.PublicRequest {\n return {\n url: `{gateway}/v1/subjects/presentations/${presentationId}/audiences`,\n publicUrl: UrlHelper.urlBuilder(`/api/subjects/presentation/${presentationId}/audiences`, {\n type: PresentationType.Subject.toLowerCase(),\n presentationId\n }),\n key: `presentation:${presentationId}:audiences`,\n normalize: false\n };\n }\n};\n","import * as React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { ChevronLeftSvg } from 'libs/shared/images/svg/arrows/ChevronLeftSvg';\n\nconst namespace = 'shared.backButton';\n\ninterface BackButtonProps {\n appLink: Core.AppLink;\n backToName?: string;\n color?: 'black' | 'white';\n extraClasses?: string;\n /**\n * Whether or not the button text has a text shadow. Defaults to true\n */\n textShadow?: boolean;\n}\n\nBackButton.defaultProps = {\n color: 'black',\n extraClasses: ''\n};\n\nexport function BackButton(props: BackButtonProps): React.ReactElement {\n const { backToName, appLink, color, extraClasses, textShadow } = {\n textShadow: true,\n ...props\n };\n\n const backPhrase = backToName ?\n LanguageService.getPhrase(namespace, 'backTo', { backToName }) :\n LanguageService.getPhrase(namespace, 'back');\n\n const colorClass = color === 'black' ? '' : 'text-white';\n const textShadowClass = textShadow ? 'text-shadow' : '';\n\n return (\n <AppLink\n appLink={appLink}\n className={`d-inline-flex align-items-center h5 mb-0 ${extraClasses} ${colorClass} ${textShadowClass}`}\n >\n <SvgContainer svg={ChevronLeftSvg} size={SvgContainerSize.Medium} />\n <span className='ms-1'>{backPhrase}</span>\n </AppLink>\n );\n}\n","import React from 'react';\n\nfunction getContainer(className: string): Element {\n return document.querySelector(`.${className}`);\n}\n\nexport interface BannerPortalContent {\n container: Element | null;\n}\n\nexport const BannerPortalContext = React.createContext<BannerPortalContent>(null);\n\ntype BannerPortalContextProviderProps = React.PropsWithChildren<{\n containerClassName: string\n}>;\n\nexport function BannerPortalContextProvider(props: BannerPortalContextProviderProps): JSX.Element {\n const [ container, setContainer ] = React.useState<Element>();\n\n React.useEffect(() => {\n setContainer(getContainer(props.containerClassName));\n }, []);\n\n return (\n <BannerPortalContext.Provider value={{ container }}>\n {props.children}\n </BannerPortalContext.Provider>\n );\n}\n","import React from 'react';\n\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { ImageMinDimensions } from 'libs/shared/constants/ImageSizes';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ImageSize, ImageType, ResizeType } from 'libs/shared/enums/Images';\nimport { Breakpoints, useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Banner, Logo } from 'libs/shared/interfaces';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\nimport { ImageHelper, ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nconst RATIO = `${ImageMinDimensions[ImageType.Banners].width}:${ImageMinDimensions[ImageType.Banners].height}`;\nconst DEFAULT_WIDTH = 1200; // This is ImageSize.Large for a Banner.\nconst LARGE_SCREEN_WIDTH = 1920;\n\nfunction getImageWidth(breakpoints: Breakpoints): number {\n if (breakpoints.xxl) return LARGE_SCREEN_WIDTH;\n\n return DEFAULT_WIDTH;\n}\n\ntype ContainerProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;\n\nfunction getContainerProps(\n banner?: Banner,\n bannerUrl?: string,\n bannerClassName?: string,\n blockColourClass?: string\n): ContainerProps {\n const containerProps: ContainerProps = {\n className: `banner banner-header ${bannerClassName}`,\n style: bannerUrl ? { backgroundImage: `url('${bannerUrl}')` } : {}\n };\n\n if (!banner && blockColourClass) {\n delete containerProps.style;\n containerProps.className += ` ${blockColourClass}`;\n }\n\n return containerProps;\n}\n\ninterface UseBannerHeaderOptions {\n heading: string;\n\n logo?: Logo;\n banner?: Banner;\n imageCdnUrl?: string;\n bannerImageOptions?: ImageOptions;\n bannerClassName?: string;\n blockColourClass?: string;\n}\n\nexport function useBannerHeader(options: UseBannerHeaderOptions) {\n const { heading, banner, logo, imageCdnUrl, bannerClassName, blockColourClass } = options;\n\n const breakpoints = useBreakpoints();\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n const imageWidth = getImageWidth(breakpoints);\n\n const bannerImageOptions = options.bannerImageOptions || {\n width: imageWidth,\n ratio: RATIO,\n resizeType: ResizeType.Cover\n };\n\n const bannerUrl =\n !!banner && !!imageCdnUrl ?\n ImageHelper.createBannerUrl(\n banner,\n {\n fallbackBaseUrl: imageCdnUrl,\n fallbackCategoryName: heading,\n type: ImageType.Banners\n },\n bannerImageOptions\n ) :\n undefined;\n\n const logoFallbackBgClassName = getBgColorClass(heading, BG_COLOUR_CLASS_NAMES);\n const logoUrl = !!logo && !!imageCdnUrl ? ImageHelper.createUrl(logo.url, { size: ImageSize.Medium }) : undefined;\n const containerProps = getContainerProps(banner, bannerUrl, bannerClassName, blockColourClass);\n\n return {\n logoUrl,\n bannerUrl,\n containerProps,\n portalContainerContext,\n logoFallbackBgClassName\n };\n}\n","@import '~styles/utils/mixins';\n@import '~styles/utils/include-media';\n:local {\n .bannerContent {\n position: absolute;\n bottom: map-get($spacers, 3);\n right: map-get($spacers, 3);\n left: map-get($spacers, 3);\n display: flex;\n align-items: flex-end;\n\n .actionsContainer {\n margin-left: auto;\n padding-left: map-get($spacers, 2);\n }\n\n @include media('<=md') {\n bottom: 1rem;\n }\n }\n\n .bannerContentWithLogo {\n right: 7rem + map-get($spacers, 3);\n }\n\n .container {\n @include media('<=xl') {\n max-width: 100%;\n }\n }\n\n .logoContainer {\n position: absolute;\n top: 50%;\n right: map-get($spacers, 3);\n transform: translateY(-50%);\n height: 60%;\n max-height: 7.5rem;\n\n img {\n height: 100%;\n }\n }\n\n .logoContainerLeft {\n width: 8rem;\n aspect-ratio: 1 / 1;\n }\n\n .logoHeading {\n max-width: 32.5rem;\n }\n\n .specialEventContainer {\n font-size: 0.8rem;\n min-width: 7rem;\n margin-right: map-get($spacers, 3);\n\n @include media('<=lg') {\n min-width: 6rem;\n font-size: 0.7rem;\n margin-right: map-get($spacers, 2);\n }\n\n @include media('<=md') {\n min-width: 5.5rem;\n font-size: 0.65rem;\n }\n\n @include media('<=sm') {\n min-width: 5rem;\n font-size: 0.6rem;\n }\n }\n\n .headingLarge {\n @include clamp(5);\n font-size: $h3-font-size;\n\n @include media(\"<xl\") {\n font-size: $h4-font-size;\n }\n\n @include media(\"<lg\") {\n @include clamp(4);\n font-size: $h5-font-size;\n }\n\n @include media(\"<md\") {\n font-size: $h6-font-size;\n }\n }\n .heading {\n @include clamp(4);\n \n @include media(\"<=sm\") {\n @include clamp(2);\n }\n \n }\n}","import * as React from 'react';\n\nimport { Core } from 'libs/common/core';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ComingSoonTag } from 'libs/shared/apps/calendar/components/coming-soon-tag/ComingSoonTag';\nimport { GenericCalendarDate } from 'libs/shared/apps/calendar/components/generic-calendar-date/GenericCalendarDate';\nimport { CalendarTheme } from 'libs/shared/apps/calendar/interfaces/CalendarTheme';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { BackButton } from 'libs/shared/components/back-button/BackButton';\nimport { LazyImage } from 'libs/shared/components/lazy-image/LazyImage';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { Banner, CalendarEvent, Logo } from 'libs/shared/interfaces';\nimport { ImageOptions } from 'libs/shared/utils/ImageHelper';\n\nimport { useBannerHeader } from '../hooks/useBannerHeader';\n\nimport styles from './default-banner-header.module.scss';\n\nfunction getSizeClass(heading: string): string {\n if (heading.length < 160)\n return 'h1';\n\n return styles.headingLarge;\n}\n\nexport interface DefaultBannerHeaderProps {\n heading: string;\n banner?: Banner;\n bannerClassName?: string;\n imageCdnUrl?: string;\n logo?: Logo;\n logoBgColour?: string;\n actions?: ActionOptions[];\n specialEvent?: CalendarEvent;\n backButtonAppLink?: Core.AppLink;\n backButtonText?: string;\n backButtonClasses?: string;\n sortComponent?: JSX.Element;\n blockColourClass?: string;\n actionsDropdownClassName?: string;\n detailsComponent?: () => React.ReactElement;\n imageOptions?: ImageOptions;\n showComingSoon?: boolean;\n alignLogoLeft?: boolean;\n calendarTheme?: CalendarTheme;\n}\n\nconst namespace = 'shared.defaultBannerHeader';\n\nexport const DefaultBannerHeader =\n React.memo(function(props: React.PropsWithChildren<DefaultBannerHeaderProps>): React.ReactElement {\n const { heading, banner, imageCdnUrl, actions, sortComponent, blockColourClass, specialEvent } = props;\n\n const {\n logoUrl,\n portalContainerContext,\n logoFallbackBgClassName,\n containerProps\n } = useBannerHeader({\n heading,\n banner,\n blockColourClass,\n bannerClassName: props.bannerClassName,\n imageCdnUrl,\n logo: props.logo,\n bannerImageOptions: props.imageOptions\n });\n\n const specialEventIsToday = React.useMemo(() => {\n if (!specialEvent || props.showComingSoon)\n return false;\n\n const today = DateHelper.format(new Date(), 'YYYY-MM-DD');\n\n if (!specialEvent.endDate)\n return specialEvent.startDate === today;\n\n return specialEvent.startDate <= today && specialEvent.endDate >= today;\n }, [specialEvent]);\n\n function getSpecialEventMonthText(specialEvent: CalendarEvent): string {\n if (!specialEvent.endDate)\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n if (DateHelper.isSame(specialEvent.startDate, specialEvent.endDate, 'month'))\n return DateHelper.format(specialEvent.startDate, 'MMMM');\n\n return `${DateHelper.format(specialEvent.startDate, 'MMM')} - ${DateHelper.format(specialEvent.endDate, 'MMM')}`;\n }\n\n const DetailsComponent = props.detailsComponent;\n\n return PortalHelper.renderInPortalIfExists(\n // \"banner\" is used in playlists in Online. banner-header is used by all other projects\n <header {...containerProps}>\n <div className={`container ${styles.container} position-relative inner-banner`}>\n {props.backButtonAppLink && (\n <div className='pt-3'>\n <BackButton\n appLink={props.backButtonAppLink}\n backToName={props.backButtonText}\n extraClasses={props.backButtonClasses}\n color='white'\n />\n </div>\n )}\n \n <div className={`${props.alignLogoLeft ? 'position-absolute top-50 start-0 translate-middle-y w-100 ps-4' : `${styles.bannerContent} px-2 ${props.logo?.url ? styles.bannerContentWithLogo : ''}`}`}>\n {!!specialEvent && (\n <div className={`position-relative ${styles.specialEventContainer}`}>\n <GenericCalendarDate\n body={{\n type: specialEvent.endDate ? 'range' : 'day',\n text: specialEvent.endDate ?\n `${DateHelper.format(specialEvent.startDate, 'DD')}-${DateHelper.format(specialEvent.endDate, 'DD')}` :\n DateHelper.format(specialEvent.startDate, 'DD')\n }}\n month={getSpecialEventMonthText(specialEvent)}\n theme={props.calendarTheme}\n />\n </div>\n )}\n <div>\n {specialEventIsToday && (\n <div className='rounded-pill py-1 px-2 my-1 me-1 fw-semibold bg-light-blue lh-1 d-inline-block'>\n <Text namespace={namespace} phrase='onToday' />\n </div>\n )}\n {props.showComingSoon && (\n <ComingSoonTag className='pe-2 fw-semibold mb-1 rounded-pill justify-content-start text-nowrap' />\n )}\n <div className='d-flex align-items-center'>\n {props.alignLogoLeft && props.logo?.url &&\n <div className={`${styles.logoContainerLeft} d-none d-md-block rounded-circle overflow-hidden me-3 ${logoFallbackBgClassName}`}>\n <LazyImage\n src={logoUrl}\n style={{ backgroundColor: props.logoBgColour }}\n />\n </div>\n }\n <h1 className={`text-white text-shadow pe-3 position-static ${styles.heading} ${getSizeClass(heading)} ${props.alignLogoLeft ? 'w-50' : ''}`}>\n {heading}\n {DetailsComponent && <DetailsComponent />}\n </h1>\n </div>\n </div>\n {!!actions && (\n <div className={styles.actionsContainer}>\n <Actions\n actions={actions}\n sortComponent={sortComponent}\n actionsDropdownClassName={props.actionsDropdownClassName}\n />\n </div>\n )}\n </div>\n {!props.alignLogoLeft && !!props.logo?.url &&\n <div className={styles.logoContainer}>\n <img\n src={logoUrl}\n className='rounded-circle'\n />\n </div>\n }\n </div>\n </header>,\n portalContainerContext?.container\n );\n }, (prevProps, nextProps): boolean => (\n prevProps.actions === nextProps.actions\n && prevProps.heading === nextProps.heading\n && prevProps.logo?.url === nextProps.logo?.url\n ));\n\nexport function PartialDefaultBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className={`partial-banner partial-loading-background ${styles.banner}`} />,\n portalContainerContext?.container\n );\n}\n","import React from 'react';\n\nimport { ContentPartnerEventLoggerFn } from 'libs/shared/apps/content-partners/utils/get-content-partner-event-logger/getContentPartnerEventLogger';\n\ninterface VideoState {\n loaded: boolean;\n isPlaying: boolean;\n isFinished: boolean;\n}\n\ninterface VideoControlsProps {\n onPlay?: () => void;\n onPause?: () => void;\n onEnd?: () => void;\n onInit?: () => void;\n onMute?: () => void;\n onUnmute?: () => void;\n /**\n * Milliseconds to delay the the `loaded` state being set to true.\n */\n addDelayOnLoad?: number;\n log?: ContentPartnerEventLoggerFn;\n}\n\nexport function useVideoControls(options?: VideoControlsProps) {\n const ref = React.useRef<HTMLVideoElement>(null);\n\n const [ videoState, setVideoState ] = React.useState<VideoState>({\n loaded: false,\n isPlaying: false,\n // Note: If `loop` is set to true, then `isFinished` will never be true.\n isFinished: false\n });\n\n function setVideoStateProperty<K extends keyof VideoState>(key: K, value: VideoState[K]) {\n setVideoState(prevState => ({ ...prevState, [key]: value }));\n }\n\n const videoEventListenerMap: {[key in keyof HTMLVideoElementEventMap]?: (event: Event) => void } = {\n loadstart: () => {\n options?.onInit?.();\n },\n canplay: () => {\n if (typeof options?.addDelayOnLoad === 'number') {\n pause();\n if (ref.current?.autoplay)\n ref.current.autoplay = false;\n \n setTimeout(() => {\n setVideoStateProperty('loaded', true);\n play();\n }, options.addDelayOnLoad);\n } else {\n setVideoStateProperty('loaded', true);\n }\n },\n play: () => {\n setVideoStateProperty('isPlaying', true);\n options?.onPlay?.();\n },\n pause: () => {\n setVideoStateProperty('isPlaying', false);\n options?.onPause?.();\n },\n ended: () => {\n setVideoState(prevState => ({ ...prevState, isPlaying: false, isFinished: true }));\n options?.onEnd?.();\n }\n };\n\n React.useEffect(() => {\n if (!Object.keys(videoEventListenerMap).length)\n return;\n\n Object.entries(videoEventListenerMap).forEach(([ event, handler ]) => {\n ref.current?.addEventListener(event, handler);\n });\n\n return () => {\n Object.entries(videoEventListenerMap).forEach(([ event, handler ]) => {\n ref.current?.removeEventListener(event, handler);\n });\n };\n }, [ref.current]);\n\n function play() {\n if (videoState.isPlaying)\n return;\n \n ref.current?.play();\n setVideoState(prevState => ({ ...prevState, isPlaying: true, isFinished: false }));\n }\n\n function pause() {\n if (!videoState.isPlaying)\n return;\n \n ref.current?.pause();\n setVideoStateProperty('isPlaying', false);\n }\n\n function togglePlayPause() {\n if (videoState.isPlaying) {\n pause();\n options?.log?.({\n type: 'click-video-banner-controls',\n control: 'pause'\n });\n } else {\n play();\n options?.log?.({\n type: 'click-video-banner-controls',\n control: 'play'\n });\n }\n }\n\n function loop() {\n if (!ref.current)\n return;\n \n ref.current.loop = true;\n }\n\n return {\n videoRef: ref,\n ...videoState,\n play,\n pause,\n togglePlayPause,\n loop\n };\n}\n\ninterface VideoProps extends React.VideoHTMLAttributes<HTMLVideoElement> {\n}\n\nexport const Video = React.forwardRef<HTMLVideoElement, VideoProps>((props, ref) => {\n const {\n autoPlay = false,\n muted = true,\n loop = false,\n controls = false,\n disablePictureInPicture = true,\n disableRemotePlayback = true,\n ...otherProps\n } = props;\n\n return (\n <video\n ref={ref}\n autoPlay={autoPlay}\n muted={muted}\n loop={loop}\n controls={controls}\n disablePictureInPicture={disablePictureInPicture}\n disableRemotePlayback={disableRemotePlayback}\n {...otherProps}\n />\n );\n});\n","import React from 'react';\n\nexport function PauseSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fillRule='evenodd'\n clipRule='evenodd'\n d='M9.5 6C8.67157 6 8 6.67157 8 7.5V16.5C8 17.3284 8.67157 18 9.5 18C10.3284 18 11 17.3284 11 16.5V7.5C11 6.67157 10.3284 6 9.5 6ZM15.5 6C14.6716 6 14 6.67157 14 7.5V16.5C14 17.3284 14.6716 18 15.5 18C16.3284 18 17 17.3284 17 16.5V7.5C17 6.67157 16.3284 6 15.5 6Z'\n />\n </svg>\n\n );\n}\n","import React from 'react';\n\nexport function LinkSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n d='M17.834 5.916a2.5 2.5 0 0 0-3.536 0L12.53 7.684a.5.5 0 0 1-.707-.707l1.768-1.768a3.5 3.5 0 1 1 4.95 4.95l-3.687 3.687a3.786 3.786 0 0 1-5.354 0l-.152-.152a.5.5 0 0 1 .707-.707l.152.152a2.786 2.786 0 0 0 3.94 0l3.687-3.687a2.5 2.5 0 0 0 0-3.536m-8.94 3.99a3.643 3.643 0 0 1 5.152 0l.606.607a.5.5 0 1 1-.707.707l-.607-.606a2.643 2.643 0 0 0-3.737 0l-3.435 3.434a2.5 2.5 0 1 0 3.536 3.536l1.414-1.415a.5.5 0 0 1 .707.707l-1.414 1.415a3.5 3.5 0 1 1-4.95-4.95z'\n />\n </svg>\n );\n}\n","export enum VideoBannerControlOption {\n PlayPause = 'play-pause',\n WebsiteLink = 'website-link'\n}\n\nexport const AllVideoBannerControlOptions: VideoBannerControlOption[] = [\n VideoBannerControlOption.PlayPause,\n VideoBannerControlOption.WebsiteLink\n];\n","import { VideoBannerControlOption } from '../enums/VideoBannerControlOption';\n\nexport type PartnerProfileBannerHeaderContentType = 'text' | 'logo' | 'sign-up' | 'logo-with-name';\n\ninterface GetBannerHeaderContentTypeOptions {\n logoUrl?: string;\n isAuthenticated: boolean;\n showVideoBanner: boolean;\n isChannelTopic?: boolean;\n}\n\nexport const PartnerProfileBannerHeaderHelper = {\n getBannerHeaderContentType(\n options: GetBannerHeaderContentTypeOptions\n ): PartnerProfileBannerHeaderContentType {\n if (options.isChannelTopic)\n return 'logo-with-name';\n\n let contentType: PartnerProfileBannerHeaderContentType = 'text';\n\n if (options.logoUrl)\n contentType = 'logo';\n\n if (!options.isAuthenticated && options.showVideoBanner)\n contentType = 'sign-up';\n\n return contentType;\n },\n\n showWebsiteLinkControls(controls: VideoBannerControlOption[], websiteUrl: string, isStudent: boolean) {\n if (isStudent)\n return false;\n\n return !!websiteUrl && controls.includes(VideoBannerControlOption.WebsiteLink);\n }\n};\n","@import '~styles/utils/mixins';\n@import '~styles/utils/include-media';\n\n:local {\n $logoContainerWidth: 13.75rem; // 220px From design and what looks good\n $logoPositionBottomOffset: 1rem; // 16px offset\n\n .videoBannerRadius {\n border-radius: 0;\n\n @include media('>=xl') {\n border-radius: $border-radius-lg;\n }\n }\n\n .nowrap {\n white-space: nowrap;\n }\n\n\n .hasLogo {\n padding-bottom: $logoPositionBottomOffset;\n }\n\n .logoPosition {\n bottom: -$logoPositionBottomOffset;\n }\n\n .logoContainer {\n width: $logoContainerWidth;\n }\n\n .container {\n @include media('<=xl') {\n max-width: 100%;\n }\n }\n\n .signUpContainer {\n $leftOffset: $logoContainerWidth + map-get($spacers, 4);\n left: calc(#{$leftOffset});\n width: calc(100% - #{$leftOffset} - map-get($spacers, 1));\n z-index: 1;\n }\n\n .signUpContent {\n @include bg-blur(10px, true);\n border-left: none;\n border-right: none;\n }\n\n .signUpHeading {\n white-space: nowrap;\n\n @include media('<=md') {\n white-space: normal;\n }\n }\n\n .emailInput {\n @include media('>=md') {\n min-width: 19.375rem; // from design\n }\n }\n\n .videoControls {\n top: 1rem;\n right: 1rem;\n transition: opacity 0.5s ease-in-out;\n }\n\n .videoContent {\n opacity: 0;\n transition: opacity 0.5s ease-in-out;\n }\n\n .videoVisible {\n opacity: 1;\n }\n}","import React from 'react';\nimport { Button } from 'react-bootstrap';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { RectangularLogo } from 'libs/shared/components/rectangular-logo/RectangularLogo';\n\nimport { PartnerProfileBannerHeaderContentType } from '../utils/PartnerProfileBannerHeaderHelper';\n\nimport styles from './partner-profile-banner-header.module.scss';\n\nconst namespace = 'bannerHeader.partnerProfileBannerHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface PartnerProfileBannerHeaderContentProps {\n type: PartnerProfileBannerHeaderContentType;\n name: string;\n onClickSignUp?: (email: string) => void;\n logoUrl?: string;\n bgColor?: string;\n}\n\nfunction BannerWithText(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className='position-absolute bottom-0 start-0 mb-3 w-100 px-4'>\n <div className='d-flex align-items-center'>\n <h1 className='text-white text-shadow pe-3 position-static mb-0'>{props.name}</h1>\n </div>\n </div>\n </div>\n );\n}\n\nfunction BannerWithLogo(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className={classNames('position-absolute start-0 px-4', styles.logoPosition)}>\n <div className={styles.logoContainer}>\n <RectangularLogo\n logoUrl={props.logoUrl}\n bgColor={props.bgColor}\n name={props.name}\n classNames={{\n container: 'border border-white'\n }}\n />\n </div>\n </div>\n </div>\n );\n}\n\nfunction BannerWithLogoAndName(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className={classNames(\n 'position-absolute start-0 px-4 d-flex align-items-center gap-3',\n styles.logoPosition\n )}>\n <div className={styles.logoContainer}>\n <RectangularLogo\n logoUrl={props.logoUrl}\n bgColor={props.bgColor}\n name={props.name}\n classNames={{\n container: 'border border-white'\n }}\n />\n </div>\n <h1 className='text-white text-shadow mb-0'>{props.name}</h1>\n </div>\n </div>\n );\n}\n\nfunction BannerWithSignUp(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n const [ email, setEmail ] = React.useState('');\n\n function onSubmit(e: React.FormEvent<HTMLFormElement>): void {\n e.preventDefault();\n props.onClickSignUp?.(email);\n }\n\n return (\n <div className={classNames('container position-relative inner-banner', styles.container)}>\n <div className={classNames('position-absolute start-0 px-4 ', styles.logoPosition)}>\n <div className={styles.logoContainer}>\n <RectangularLogo\n logoUrl={props.logoUrl}\n bgColor={props.bgColor}\n name={props.name}\n classNames={{\n container: 'border border-white'\n }}\n />\n </div>\n </div>\n <div\n className={classNames(\n 'position-absolute bottom-0 pb-2 pb-md-3 px-0 px-sm-3 d-none d-xl-block',\n styles.signUpContainer\n )}\n >\n <div\n className={classNames(\n 'd-flex align-items-center justify-content-between gap-2 flex-wrap rounded-3 p-3',\n styles.signUpContent\n )}\n >\n <div className='d-sm-flex align-items-center gap-2 '>\n <h4 className={classNames('text-white text-shadow mb-0', styles.signUpHeading)}>\n {getPhrase('description')}\n </h4>\n </div>\n <form className='d-flex align-items-center gap-2 flex-grow-1 flex-md-grow-0' onSubmit={onSubmit}>\n <input\n type='email'\n className={classNames('form-control w-100', styles.emailInput)}\n placeholder={getPhrase('emailPlaceholder')}\n value={email}\n onChange={e => setEmail(e.target.value)}\n />\n <Button type='submit' variant='dark' className={styles.nowrap}>\n {getPhrase('cta')}\n </Button>\n </form>\n </div>\n </div>\n </div>\n );\n}\n\nconst HeaderTypeContentMap: Record<\n PartnerProfileBannerHeaderContentType,\n React.ComponentType<PartnerProfileBannerHeaderContentProps>\n> = {\n 'logo': BannerWithLogo,\n 'logo-with-name': BannerWithLogoAndName,\n 'sign-up': BannerWithSignUp,\n 'text': BannerWithText\n};\n\nexport function PartnerProfileBannerHeaderContent(props: PartnerProfileBannerHeaderContentProps): JSX.Element {\n const ContentComponent = HeaderTypeContentMap[props.type];\n return <ContentComponent {...props} />;\n}\n","import React from 'react';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { PortalHelper } from 'libs/common/react/utils/PortalHelper';\n\nimport { ContentPartnerEventLoggerFn } from 'libs/shared/apps/content-partners/utils/get-content-partner-event-logger/getContentPartnerEventLogger';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { useVideoControls, Video } from 'libs/shared/components/video/Video';\nimport { BannerPortalContext } from 'libs/shared/context/BannerPortalContext';\nimport { ResizeType } from 'libs/shared/enums/Images';\nimport { PauseSvg } from 'libs/shared/images/svg/actions/PauseSvg';\nimport { PlaySvg } from 'libs/shared/images/svg/actions/PlaySvg';\nimport { LinkSvg } from 'libs/shared/images/svg/objects/LinkSvg';\nimport { Banner, Logo } from 'libs/shared/interfaces';\n\nimport { AllVideoBannerControlOptions, VideoBannerControlOption } from '../enums/VideoBannerControlOption';\nimport { useBannerHeader } from '../hooks/useBannerHeader';\nimport { PartnerProfileBannerHeaderHelper } from '../utils/PartnerProfileBannerHeaderHelper';\n\nimport { PartnerProfileBannerHeaderContent } from './PartnerProfileBannerHeaderContent';\n\nimport styles from './partner-profile-banner-header.module.scss';\n\nconst namespace = 'bannerHeader.partnerProfileBannerHeader';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface VideoBannerContentProps {\n videoUrl: string;\n className?: string;\n videoRef: React.RefObject<HTMLVideoElement>;\n loop?: boolean;\n}\n\nfunction VideoBannerContent(props: VideoBannerContentProps): JSX.Element {\n return (\n <div className={classNames('position-absolute top-0 start-0 w-100 h-100 overflow-hidden', props.className, styles.videoBannerRadius)}>\n <Video ref={props.videoRef} autoPlay muted controls={false} loop={props.loop} className='w-100 h-100 object-fit-cover position-relative'>\n <source src={props.videoUrl} type='video/mp4' />\n </Video>\n </div>\n );\n}\n\ninterface VideoBannerControlsProps {\n isPlaying: boolean;\n togglePlayPause: () => void;\n className?: string;\n controls?: VideoBannerControlOption[];\n websiteUrl?: string;\n isStudent: boolean;\n log?: ContentPartnerEventLoggerFn;\n}\n\nfunction VideoBannerControls(props: VideoBannerControlsProps): JSX.Element {\n const PlayPauseIcon = props.isPlaying ? PauseSvg : PlaySvg;\n\n function onClickWebsiteLink(): void {\n if (!props.websiteUrl) return;\n LocationUtils.PageLoad(props.websiteUrl, true);\n props.log?.({\n type: 'click-video-banner-controls',\n control: 'website-link'\n });\n }\n \n const controls = props.controls || AllVideoBannerControlOptions;\n const showWebsiteLinkControls = PartnerProfileBannerHeaderHelper.showWebsiteLinkControls(\n controls,\n props.websiteUrl,\n props.isStudent\n );\n\n return (\n <div className={classNames(\n styles.videoControls,\n 'position-absolute d-flex gap-2 ',\n props.isPlaying && 'banner-header-video--controls',\n props.className\n )}>\n {showWebsiteLinkControls && (\n <IconButton\n svg={LinkSvg}\n svgSize={SvgContainerSize.Standard}\n className='bg-gray-200 rounded-circle cursor-pointer'\n onClick={onClickWebsiteLink}\n ariaLabel={getPhrase('viewWebsite')}\n role='button'\n tooltip={getPhrase('viewWebsite')}\n tooltipTrigger={[ 'hover', 'focus' ]}\n />\n )}\n {controls.includes(VideoBannerControlOption.PlayPause) && (\n <IconButton\n svg={PlayPauseIcon}\n svgSize={SvgContainerSize.Standard}\n className='bg-gray-200 rounded-circle cursor-pointer'\n onClick={props.togglePlayPause}\n ariaLabel={props.isPlaying ? getPhrase('pause') : getPhrase('play')}\n role='button'\n tooltip={props.isPlaying ? getPhrase('pause') : getPhrase('play')}\n tooltipTrigger={[ 'hover', 'focus' ]}\n />\n )}\n </div>\n );\n}\n\nexport function PartialPartnerProfileBannerHeader(): JSX.Element {\n const portalContainerContext = React.useContext(BannerPortalContext);\n\n return PortalHelper.renderInPortalIfExists(\n <div className='partial-banner partial-loading-background' />,\n portalContainerContext?.container\n );\n}\n\nexport type PartnerBannerHeaderType = 'static' | 'video';\n\nexport interface PartnerProfileBannerHeaderProps {\n heading: string;\n type?: 'partner-profile' | 'channel-topic';\n onClickSignUp?: (email: string) => void;\n isAuthenticated?: boolean;\n isStudent?: boolean;\n partnerBannerType?: PartnerBannerHeaderType;\n banner?: Banner;\n logo?: Logo;\n videoUrl?: string;\n imageCdnUrl?: string;\n logoBgColour?: string;\n actions?: ActionOptions[];\n blockColourClass?: string;\n websiteUrl?: string;\n log?: ContentPartnerEventLoggerFn;\n}\n\nconst VIDEO_BANNER_WIDTH = 1920;\nconst VIDEO_BANNER_RATIO = '1200:330';\n\nexport function PartnerProfileBannerHeader(props: PartnerProfileBannerHeaderProps): JSX.Element {\n const { heading, isAuthenticated, partnerBannerType = 'static', websiteUrl } = props;\n\n const isChannelTopic = props.type === 'channel-topic';\n\n const {\n videoRef,\n isPlaying,\n isFinished,\n loaded,\n togglePlayPause\n } = useVideoControls({\n addDelayOnLoad: 2500,\n log: props.log\n });\n\n // channel-topic banners never show the video banner or the sign-up CTA.\n const showVideoBanner = !isChannelTopic && partnerBannerType === 'video' && !!props.videoUrl;\n const isVideoVisible = loaded && !isFinished;\n\n const { containerProps, portalContainerContext, logoUrl } = useBannerHeader({\n heading,\n banner: props.banner,\n logo: props.logo,\n imageCdnUrl: props.imageCdnUrl,\n blockColourClass: props.blockColourClass,\n bannerClassName: classNames(\n showVideoBanner && 'banner-header-video position-relative',\n showVideoBanner && styles.videoBannerRadius\n ),\n bannerImageOptions: showVideoBanner ? {\n width: VIDEO_BANNER_WIDTH,\n ratio: VIDEO_BANNER_RATIO,\n resizeType: ResizeType.Cover\n } : null\n });\n\n const contentType = PartnerProfileBannerHeaderHelper.getBannerHeaderContentType({\n logoUrl,\n isAuthenticated,\n showVideoBanner,\n isChannelTopic\n });\n\n const showLogo = contentType === 'logo' || contentType === 'sign-up' || contentType === 'logo-with-name';\n const controls = isVideoVisible ?\n AllVideoBannerControlOptions :\n [ VideoBannerControlOption.PlayPause, VideoBannerControlOption.WebsiteLink ];\n \n return PortalHelper.renderInPortalIfExists(\n <header className={classNames(\n styles.header,\n showVideoBanner && 'px-0 px-xl-3 pt-xl-3 ',\n showLogo && styles.hasLogo\n )}>\n <div {...containerProps}>\n {showVideoBanner && (\n <VideoBannerContent\n videoUrl={props.videoUrl}\n videoRef={videoRef}\n className={classNames(styles.videoContent, isVideoVisible && styles.videoVisible)}\n // If loop is true then isFinished will never be true.\n loop={!props.banner}\n />\n )}\n <PartnerProfileBannerHeaderContent\n type={contentType}\n name={heading}\n logoUrl={logoUrl}\n bgColor={props.logoBgColour}\n onClickSignUp={props.onClickSignUp}\n />\n {showVideoBanner && (\n <VideoBannerControls\n isPlaying={isPlaying}\n togglePlayPause={togglePlayPause}\n controls={controls}\n websiteUrl={websiteUrl}\n isStudent={props.isStudent}\n log={props.log}\n />\n )}\n </div>\n </header>,\n portalContainerContext?.container\n );\n}\n","import React from 'react';\n\nimport {\n DefaultBannerHeader,\n DefaultBannerHeaderProps,\n PartialDefaultBannerHeader\n} from './default-banner-header/DefaultBannerHeader';\nimport {\n PartialPartnerProfileBannerHeader,\n PartnerProfileBannerHeader,\n PartnerProfileBannerHeaderProps\n} from './partner-profile-banner-header/PartnerProfileBannerHeader';\n\ntype InternalDefaultBannerHeaderProps = DefaultBannerHeaderProps & {\n type?: 'default'\n};\n\ntype InternalPartnerProfileBannerHeaderProps = PartnerProfileBannerHeaderProps & {\n type?: 'partner-profile'\n};\n\ntype InternalChannelTopicBannerHeaderProps = PartnerProfileBannerHeaderProps & {\n type?: 'channel-topic'\n};\n\ntype BannerHeaderProps =\n InternalDefaultBannerHeaderProps |\n InternalPartnerProfileBannerHeaderProps |\n InternalChannelTopicBannerHeaderProps;\n\ntype BannerType = BannerHeaderProps['type'];\ntype BannerTypeOptions = {\n Component: React.ComponentType<any>,\n PartialComponent: React.ComponentType<any>\n};\n\nconst bannerTypeMap: Record<BannerType, BannerTypeOptions> = {\n 'default': {\n Component: DefaultBannerHeader,\n PartialComponent: PartialDefaultBannerHeader\n },\n 'partner-profile': {\n Component: PartnerProfileBannerHeader,\n PartialComponent: PartialPartnerProfileBannerHeader\n },\n 'channel-topic': {\n Component: PartnerProfileBannerHeader,\n PartialComponent: PartialPartnerProfileBannerHeader\n }\n};\n\nexport function BannerHeader(props: BannerHeaderProps): JSX.Element {\n const { type = 'default' } = props;\n\n const Component = bannerTypeMap[type].Component;\n return <Component {...props} />;\n}\n\ninterface PartialBannerHeaderProps {\n type?: BannerType;\n}\n\nexport function PartialBannerHeader(props: PartialBannerHeaderProps): JSX.Element {\n const { type = 'default' } = props;\n\n const PartialComponent = bannerTypeMap[type].PartialComponent;\n return <PartialComponent {...props} />;\n}\n","import React from 'react';\n\nimport { Middleware, type MiddlewareFunctionSync } from 'libs/common/backbone/core';\n\nexport type UseTransformerFunc<T> = (options: T) => T;\n\nexport function useTransformer<T>(transformations?: MiddlewareFunctionSync<T>[]) {\n const middleware = React.useMemo(() => new Middleware<T>(), []);\n\n React.useEffect(() => {\n if (!transformations || !transformations.length)\n return;\n\n transformations.forEach(fn => middleware.useSync(fn));\n }, []);\n\n function push(fn: MiddlewareFunctionSync<T>): void {\n if (!middleware)\n return;\n\n middleware.useSync(fn);\n }\n\n function execute(options: T): T {\n if (!middleware)\n return;\n \n return middleware.goSync(options);\n }\n \n return {\n push,\n execute\n };\n}\n","import React from 'react';\n\nimport { HttpStatus } from 'libs/common/backbone/enums/HttpStatus';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { handleHttpError } from 'libs/shared/errors/handlers/HttpErrorHandlers';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useInfiniteList } from 'libs/shared/hooks/UseInfiniteList';\nimport { useLazyLoad } from 'libs/shared/hooks/UseLazyLoad';\nimport { useTransformer, UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { BaseWidget } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.useInfiniteWidgetFetch';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface UseInfiniteWidgetFetchOptions<TItem, TWidget> {\n item: TItem;\n infiniteFetch: boolean;\n getRequest: (cursor?: string) => Flight.Request;\n getCursor: (widget: TWidget) => string;\n setIsEmpty?: (isEmpty: boolean) => void;\n isEmptyPredicate?: (items: TWidget[]) => boolean;\n \n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n}\n\nexport function useInfiniteWidgetFetch<\n TItem extends BaseWidget,\n TWidget extends BaseWidget\n>(options: UseInfiniteWidgetFetchOptions<TItem, TWidget>) {\n const fetch = Flight.useGetFetch();\n const alerts = useAlerts();\n const { ref: partialLoadingRef, inView } = useLazyLoad();\n const resultsTransformers = useTransformer<TWidget[]>(options.resultsTransformers ?? []);\n const widgetItemTransformers = useTransformer<TWidget>(options.widgetItemTransformers ?? []);\n \n function fetchNext(cursor?: string) {\n return fetch(options.getRequest(cursor));\n }\n\n function onError(pageNumber: number, httpStatus: HttpStatus): void {\n if (pageNumber === 1)\n return handleHttpError(httpStatus);\n\n alerts.error(getPhrase('error'));\n }\n \n function getItems(response: TWidget) {\n return [response];\n }\n \n const fetchResults = useInfiniteList<TWidget, TWidget>(\n inView && options.getRequest,\n inView && fetchNext,\n onError,\n getItems,\n options.infiniteFetch && options.getCursor\n );\n\n function transformResults(data: TWidget[]): TWidget[] {\n if (!data || !data.length)\n return;\n\n const results = resultsTransformers.execute(data);\n\n if (!options.widgetItemTransformers?.length)\n return results;\n\n const transformedResults = results.map(item => widgetItemTransformers.execute(item));\n\n return transformedResults;\n }\n\n /**\n * This is an array of widgets because technically we can have same widget type id\n * but different template id. This is the case the search series widget.\n */\n const items = transformResults(fetchResults.items);\n\n /**\n * Side effects below\n */\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted || !items)\n return;\n\n if (!options.onLoadWidgetsTriggers?.length || !items.length)\n return;\n\n options.onLoadWidgetsTriggers.forEach(onLoad => onLoad(items));\n }, [ fetchResults.hasFirstPageCompleted, items ]);\n\n React.useEffect(() => {\n if (!fetchResults.hasFirstPageCompleted)\n return;\n\n if (!items) {\n options.setIsEmpty?.(true);\n return;\n }\n\n if (Array.isArray(items) && !items.length) {\n options.setIsEmpty?.(true);\n return;\n }\n\n if (!options.isEmptyPredicate)\n return;\n\n /**\n * For some reason our widget data structure is different for different dashboard targets.\n * Since it is inconsistent we can use the custom isEmptyPredicate check if the default\n * check above does not handle the use case.\n */\n options.setIsEmpty?.(options.isEmptyPredicate(items));\n }, [ fetchResults.hasFirstPageCompleted, options.isEmptyPredicate ]);\n\n const isEmpty = !items?.length;\n const showLoading = !fetchResults.hasFirstPageCompleted;\n const showInfiniteScrollFooter = options.infiniteFetch && (fetchResults.hasMore || fetchResults.isFetching);\n\n return {\n widgets: items,\n isEmpty,\n showLoading,\n showInfiniteScrollFooter,\n isFetching: fetchResults.isFetching,\n nextCursor: fetchResults.nextCursor,\n fetchNext,\n partialLoadingRef\n };\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\n\nimport { HashObject } from 'libs/analytics/interfaces';\n\nimport { InfiniteScrollFooter } from 'libs/shared/components/infinite-scroll-footer/InfiniteScrollFooter';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllWidgetTemplateProps } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { type HasLocalPermissionsFunc, type HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { UseTransformerFunc } from 'libs/shared/hooks/useTransformer';\nimport { type BaseObject, BaseWidget, CalendarEventContentType, type CurrentUser, CurriculumData, DashboardTargetType, type Presentation, type PresentationAudience, WidgetMetadata } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nimport { useInfiniteWidgetFetch } from './hooks/useInfiniteWidgetFetch';\n\ntype InferredWidgetTemplateProps = {\n appLinks: any,\n appLinkOptions?: any\n};\n\n/**\n * Props for InfiniteWidgetContainerView component\n *\n * @template TItem - The type of the widget item (extends BaseWidget)\n * @template TWidget - The type of individual widget content (extends BaseWidget)\n * @template TWidgetTemplateProps - The widget template props type for type-safe appLinks and appLinkOptions\n *\n * Use TWidgetTemplateProps to get type safety for specific dashboard targets:\n * @example\n * // For Search dashboard with type safety:\n * import { AllSearchWidgetTemplates } from './WidgetProps';\n *\n * <InfiniteWidgetContainerView<MyItem, MyWidget, AllSearchWidgetTemplates>\n * dashboardTarget={DashboardTargetType.Search}\n * appLinks={searchAppLinks} // Typed as AllSearchWidgetTemplates['appLinks']\n * appLinkOptions={searchAppLinkOptions} // Typed as AllSearchWidgetTemplates['appLinkOptions']\n * // ... other props\n * />\n */\ninterface InfiniteWidgetContainerViewProps<\n TItem,\n TWidget,\n TWidgetTemplateProps extends InferredWidgetTemplateProps = AllWidgetTemplateProps\n> {\n index: number;\n item: TItem;\n /**\n * If set to false will only fetch the first page\n */\n infiniteFetch: boolean;\n\n currentUser?: CurrentUser;\n audiences: PresentationAudience[];\n commonVideoProps: CommonVideoProps;\n dashboardTarget?: DashboardTargetType;\n availablePresentations?: Presentation[];\n presentation?: Presentation;\n\n analyticsData?: HashObject;\n imageCdnUrl?: string;\n imageUrls?: AllWidgetTemplateProps['imageUrls'];\n resourceThumbnailFallbackImageUrl?: string;\n lazyLoad?: boolean;\n\n headingElementRef?: React.MutableRefObject<Set<Element>>;\n hasTableOfContents?: boolean;\n isScrollToTargetWidget?: boolean;\n isBot?: boolean;\n isPreviewing?: boolean;\n isEditing?: boolean;\n curriculums?: CurriculumData;\n contentType?: CalendarEventContentType;\n\n /**\n * App links - type is determined by TWidgetTemplateProps generic parameter\n * Defaults to AllWidgetTemplateProps['appLinks'] if not specified\n */\n appLinks: TWidgetTemplateProps['appLinks'];\n\n /**\n * App link options - type is determined by TWidgetTemplateProps generic parameter\n * Defaults to AllWidgetTemplateProps['appLinkOptions'] if not specified\n */\n appLinkOptions?: TWidgetTemplateProps['appLinkOptions'];\n\n settingsHash?: SettingsHash;\n hasPermissions: HasPermissionsFunc;\n getName: (widget: TWidget) => string;\n getPartialLoadingPredicate?: () => boolean;\n hasLocalPermissions: HasLocalPermissionsFunc;\n getWidgetClassName?: (widget: TWidget) => string;\n getBadgeComponent?: (widget: TWidget) => JSX.Element;\n getSeeMoreAppLink?: (widget: TWidget) => Core.AppLink;\n getSelectedItems: (type: WidgetTypeId) => BaseObject[];\n getWidgetMetadata: (widget: TWidget) => Partial<WidgetMetadata>;\n getAnalyticsData?: (widget: TWidget, yIndex: number, xIndex: number) => HashObject;\n \n getCursor: (widget: TWidget) => string;\n getRequest: (cursor?: string) => Flight.Request;\n setIsEmpty?: (isEmpty: boolean) => void;\n getContent?: (widget: TWidget) => BaseObject[];\n\n /**\n * A predicate to determine if the widget is empty. \n * This is used to determine if the widget should be displayed as empty. \n * If not provided, the widget will be displayed as empty if the content is empty. \n * Only to be used if the widget data structure is inconsistent for different dashboard targets. \n */\n isEmptyPredicate?: (items: TWidget[]) => boolean;\n \n /**\n * Array of transformers to be applied to results before rendering\n */\n resultsTransformers?: Array<UseTransformerFunc<TWidget[]>>;\n /**\n * Array of transformers to be applied to each widget item before rendering\n */\n widgetItemTransformers?: Array<UseTransformerFunc<TWidget>>;\n /**\n * Array of callbacks to be executed when widget is first loaded\n */\n onLoadWidgetsTriggers?: Array<(data: TWidget[]) => void>;\n onClickSearchAllVideos?: () => void;\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function InfiniteWidgetContainerView<\n TItem extends BaseWidget = BaseWidget,\n TWidget extends BaseWidget = BaseWidget,\n TWidgetTemplateProps extends InferredWidgetTemplateProps = AllWidgetTemplateProps\n>(props: InfiniteWidgetContainerViewProps<TItem, TWidget, TWidgetTemplateProps>): JSX.Element {\n const {\n isEmpty,\n widgets,\n partialLoadingRef,\n showLoading,\n fetchNext,\n isFetching,\n nextCursor,\n showInfiniteScrollFooter\n } = useInfiniteWidgetFetch({\n getRequest: props.getRequest,\n getCursor: props.getCursor,\n setIsEmpty: props.setIsEmpty,\n isEmptyPredicate: props.isEmptyPredicate,\n item: props.item,\n infiniteFetch: props.infiniteFetch,\n resultsTransformers: props.resultsTransformers,\n onLoadWidgetsTriggers: props.onLoadWidgetsTriggers,\n widgetItemTransformers: props.widgetItemTransformers\n });\n\n const template = WidgetTemplateConfig[props.item.templateId];\n const PartialTemplate = template.partialLoading;\n\n if (!template || !showLoading && isEmpty)\n return <></>;\n\n if (showLoading) {\n return (\n <div ref={partialLoadingRef} className='py-2'>\n <PartialTemplate\n name={props.item.name}\n description={props.item?.description}\n predicate={props?.getPartialLoadingPredicate}\n />\n </div>\n );\n }\n\n return (\n <>\n {widgets.map((widget, index) => {\n const isLastItem = index === widgets.length - 1;\n return (\n <React.Fragment key={`${widget.widgetId}-${widget.templateId}-${index}`}>\n <WidgetContainerView\n id={widget.id}\n widgetIndex={props.item.index}\n dashboardTarget={props.dashboardTarget}\n\n appLinks={props.appLinks}\n appLinkOptions={props.appLinkOptions}\n audiences={props.audiences}\n content={props.getContent?.(widget) ?? widget.content.data}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n currentUser={props.currentUser}\n commonVideoProps={props.commonVideoProps}\n availablePresentations={props.availablePresentations}\n presentation={props.presentation}\n\n analyticsData={props.analyticsData}\n imageCdnUrl={props.imageCdnUrl}\n imageUrls={props.imageUrls}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n lazyLoad={props.lazyLoad}\n\n name={props.getName(widget)}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n getSelectedItems={props.getSelectedItems}\n metadata={props.getWidgetMetadata(widget)}\n seeMoreLink={props.getSeeMoreAppLink?.(widget)}\n badgeComponent={props.getBadgeComponent?.(widget)}\n getAnalyticsData={\n props.getAnalyticsData && (xIndex => props.getAnalyticsData(widget, props.index, xIndex))\n }\n className={props.getWidgetClassName?.(widget)}\n\n headingElementRef={props.headingElementRef}\n hasTableOfContents={props.hasTableOfContents}\n isScrollToTargetWidget={props.isScrollToTargetWidget}\n isBot={props.isBot}\n isEditing={props.isEditing}\n curriculums={props.curriculums}\n contentType={props.contentType}\n\n settings={null}\n settingsHash={props.settingsHash}\n description={null}\n isPreviewing={props.isPreviewing ?? false}\n onClickRemoveItem={null}\n onClickSearchAllVideos={props.onClickSearchAllVideos}\n />\n {showInfiniteScrollFooter && isLastItem && (\n <InfiniteScrollFooter\n isFetching={isFetching}\n fetchNext={fetchNext}\n fetchOnScroll\n nextCursor={nextCursor}\n />\n )}\n </React.Fragment>\n );\n })}\n </>\n );\n}\n","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { CuratedWidget } from 'libs/shared/interfaces';\n\nexport function useEmptyWidgets(widgets: CuratedWidget[]) {\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n\n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n function isEmptyWidget(widgetId: string): boolean {\n return emptyWidgets[widgetId] === true;\n }\n\n function setEmptyWidget(widgetId: string, isEmpty: boolean): void {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n setEmptyWidgets(newEmptyState);\n }\n\n return {\n emptyWidgets,\n isEmptyWidget,\n setEmptyWidget,\n setEmptyWidgets\n };\n}\n","import React from 'react';\n\nimport { useResizeListener } from 'libs/shared/hooks/UseResizeListener';\n\nexport function useExpandableTextButton() {\n const containerRef = React.useRef<HTMLDivElement>(null);\n const [ showButton, setShowButton ] = React.useState(false);\n\n function showOrHideButton() {\n if (containerRef.current)\n setShowButton(containerRef.current.scrollHeight > containerRef.current.clientHeight);\n }\n\n // Show or hide the button when the containerRef is initially set\n React.useEffect(() => {\n showOrHideButton();\n }, [containerRef.current]);\n\n // Show or hide the button when the window is resized\n useResizeListener(() => {\n showOrHideButton();\n });\n\n return { containerRef, showButton };\n}\n",":local {\n .collapsed {\n overflow: hidden;\n max-height: calc(var(--lines) * 1lh);\n }\n\n .spacer {\n float: right;\n height: 100%;\n width: 0;\n }\n\n .moreButton {\n float: right;\n clear: right;\n }\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { useExpandableTextButton } from 'libs/shared/hooks/useExpandableTextButton';\n\nimport styles from './expandable-text-inline.module.scss';\n\ninterface ExpandableTextInlineProps {\n children: (props: { expanded: boolean }) => JSX.Element;\n lines?: number;\n}\n\nconst namespace = 'shared.expandableTextInline';\n\nexport function ExpandableTextInline(props: ExpandableTextInlineProps): JSX.Element {\n const { lines = 1 } = props;\n const [ expanded, setExpanded ] = React.useState(false);\n\n const { containerRef, showButton } = useExpandableTextButton();\n const TextComponent = props.children;\n\n return (\n <div\n ref={containerRef}\n style={{ '--lines': lines } as unknown as React.CSSProperties}\n className={classNames(!expanded && styles.collapsed)}\n >\n {!expanded && showButton && (\n <>\n <span className={styles.spacer} />\n <DivButton\n onClick={() => setExpanded(true)}\n className={classNames(styles.moreButton, 'text-dark hover-text-underline')}\n >\n <Text namespace={namespace} phrase='more' />\n </DivButton>\n </>\n )}\n <TextComponent expanded={expanded} />\n {(expanded) && (\n <DivButton\n onClick={() => setExpanded(false)}\n className='text-dark hover-text-underline text-underline'\n >\n <Text namespace={namespace} phrase='less' />\n </DivButton>\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\n\nimport { ContentPartnersHelper } from 'libs/shared/apps/content-partners/utils/ContentPartnersHelper';\nimport { ExpandableTextInline } from 'libs/shared/components/expandable-text-inline/ExpandableTextInline';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { LinkSvg } from 'libs/shared/images/svg/objects/LinkSvg';\nimport { PartnerProfile } from 'libs/shared/interfaces';\n\ninterface ChannelDashboardDescriptionProps {\n partnerProfile: PartnerProfile;\n}\n\nexport function ChannelDashboardDescription(props: ChannelDashboardDescriptionProps): JSX.Element {\n const websiteLink = ContentPartnersHelper.getPartnerLinkByType(\n props.partnerProfile?.links,\n 'website',\n ContentPartnersHelper.makeUTMs({ slug: props.partnerProfile._slug.value })\n );\n\n const displayWebsiteLink = UrlHelper.getHostname(websiteLink) ?? websiteLink;\n\n return (\n <div className='mt-3'>\n <ExpandableTextInline>\n {() => (\n <p className='mb-0'>\n {websiteLink && (\n <>\n <a\n href={websiteLink}\n target='_blank'\n rel='noopener noreferrer'\n className='position-relative d-inline-block ps-4 mb-2 me-2'\n >\n <SvgContainer svg={LinkSvg} className='svg-container position-absolute top-50 start-0 translate-middle-y' />\n <span className='ps-1'>{displayWebsiteLink}</span>\n </a>\n <span className='mb-2 me-2'>&bull;</span>\n </>\n )}\n {props.partnerProfile.description}\n </p>\n )}\n </ExpandableTextInline>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'contentPartners.contentPartnerDashboardComingSoon';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface ContentPartnerDashboardComingSoonProps {\n partnerName: string;\n comingSoonImageUrl: string;\n}\n\nexport function ContentPartnerDashboardComingSoon(props: ContentPartnerDashboardComingSoonProps): JSX.Element {\n return (\n <EmptyState>\n <EmptyState.Image\n src={props.comingSoonImageUrl}\n altText={getPhrase('description', { partnerName: props.partnerName })}\n />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='description' options={{ partnerName: props.partnerName }} />\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'contentPartners.contentPartnerDashboardContentRegion';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface ContentPartnerDashboardContentRegionProps {\n contentRegionImageUrl: string;\n contentRegionButtonLink: Core.AppLink;\n}\n\nexport function ContentPartnerDashboardContentRegion(props: ContentPartnerDashboardContentRegionProps): JSX.Element {\n return (\n <EmptyState>\n <EmptyState.Image src={props.contentRegionImageUrl} altText={getPhrase('imageAlt')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Cta text={getPhrase('cta')} appLink={props.contentRegionButtonLink} className='btn btn-dark' />\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'contentPartners.contentPartnerDashboardNoContent';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface ContentPartnerDashboardNoContentProps {\n noContentImageUrl: string;\n}\n\nexport function ContentPartnerDashboardNoContent(props: ContentPartnerDashboardNoContentProps): JSX.Element {\n return (\n <EmptyState>\n <EmptyState.Image\n src={props.noContentImageUrl}\n altText={getPhrase('description')}\n />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='description' />\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport {\n ContentPartnerDashboardComingSoon,\n ContentPartnerDashboardComingSoonProps\n} from '../content-partner-dashboard-coming-soon/ContentPartnerDashboardComingSoon';\nimport {\n ContentPartnerDashboardContentRegion,\n ContentPartnerDashboardContentRegionProps\n} from '../content-partner-dashboard-content-region/ContentPartnerDashboardContentRegion';\nimport {\n ContentPartnerDashboardNoContent,\n ContentPartnerDashboardNoContentProps\n} from '../content-partner-dashboard-no-content/ContentPartnerDashboardNoContent';\n\nexport type ContentPartnerEmptyStateType = 'coming-soon' | 'content-region' | 'no-content';\n\nconst ContentParterEmptyStateTypes: Record<ContentPartnerEmptyStateType, React.ComponentType<any>> = {\n 'coming-soon': ContentPartnerDashboardComingSoon,\n 'content-region': ContentPartnerDashboardContentRegion,\n 'no-content': ContentPartnerDashboardNoContent\n};\n\ntype EmptyStateType<TType extends ContentPartnerEmptyStateType, TProps> = TProps & {\n type: TType\n};\n\ntype ContentPartnerEmptyStateProps =\n EmptyStateType<'coming-soon', ContentPartnerDashboardComingSoonProps> |\n EmptyStateType<'content-region', ContentPartnerDashboardContentRegionProps> |\n EmptyStateType<'no-content', ContentPartnerDashboardNoContentProps>;\n\nexport function ContentPartnerEmptyState(props: ContentPartnerEmptyStateProps): JSX.Element {\n const Component = ContentParterEmptyStateTypes[props.type];\n\n return <Component {...props} />;\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ContentPartnersHelper } from 'libs/shared/apps/content-partners/utils/ContentPartnersHelper';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { InfiniteWidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/InfiniteWidgetContainerView';\nimport { AllPartnerProfileWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useEmptyWidgets } from 'libs/shared/hooks/useEmptyWidgets';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetQueryParams, CurrentUser, DashboardStatus, DashboardTargetType, PartnerProfile, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { ContentPartnerEventLoggerFn } from '../../utils/get-content-partner-event-logger/getContentPartnerEventLogger';\n\nimport { ChannelDashboardDescription } from './channel-dashboard-description/ChannelDashboardDescription';\nimport { ContentPartnerEmptyState, ContentPartnerEmptyStateType } from './empty-state/content-partner-empty-state/ContentPartnerEmptyState';\n\nconst InfiniteFetchWidgetIds: WidgetTypeId[] = [WidgetTypeId.ContentPartnerVideos];\n\nfunction shouldInfiniteFetch(widgets: CuratedWidget[], index: number): boolean {\n const currentWidget = widgets[index];\n\n if (!currentWidget) return false;\n \n return InfiniteFetchWidgetIds.includes(currentWidget.widgetId) && index === widgets.length - 1;\n}\n\nexport interface ContentPartnerDashboardProps {\n dashboard: CuratedDashboard;\n partnerProfile: PartnerProfile;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation?: Presentation,\n cursor?: string\n ) => Flight.Request;\n commonVideoProps: CommonVideoProps;\n getBannerActions?: () => ActionOptions[];\n breadcrumbs?: Breadcrumb[];\n isReadonly?: boolean;\n widgetAppLinks?: AllPartnerProfileWidgetTemplates['appLinks'];\n scrollToWidgetId?: string;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n settings?: AllPartnerProfileWidgetTemplates['settings'];\n audiences?: PresentationAudience[];\n currentUser?: CurrentUser;\n emptyImageUrl?: string;\n lazyLoad?: boolean;\n isBot?: boolean;\n isComingSoon?: boolean;\n isPreviewing?: boolean;\n isAuthenticated?: boolean;\n isInContentRegion: boolean;\n onClickSignUp: (email: string) => void;\n onClickSearchAllVideos?: () => void;\n getSeeMoreAppLink?: (widget: CuratedWidget) => Core.AppLink;\n log?: ContentPartnerEventLoggerFn;\n}\n\nexport function ContentPartnerDashboard(props: ContentPartnerDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { emptyWidgets, setEmptyWidget } = useEmptyWidgets(widgets);\n\n function getWidgetContentRequest(\n id: string,\n widgetTypeId: WidgetTypeId,\n template: WidgetTemplate,\n cursor?: string\n ): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template, undefined, cursor);\n }\n\n function getEmptyStateType(): ContentPartnerEmptyStateType | false {\n if (!props.isInContentRegion)\n return 'content-region';\n \n if (props.isComingSoon)\n return 'coming-soon';\n \n if (props.dashboard.status === DashboardStatus.Archived && !props.isReadonly)\n return 'coming-soon';\n \n if (props.dashboard.status === DashboardStatus.Draft && !props.isPreviewing)\n return false;\n\n if (!widgets?.length)\n return 'no-content';\n \n const emptyValues = Object.values(emptyWidgets);\n \n if (emptyValues.length > 0 && emptyValues.every(state => !!state))\n return 'no-content';\n\n return false;\n }\n\n const bannerInfo = ContentPartnersHelper.getPartnerBannerInfo(props.partnerProfile);\n\n const emptyState = getEmptyStateType();\n const showExpandableDescription = (!emptyState || emptyState === 'content-region') && props.partnerProfile.description;\n\n return (\n <>\n {!!widgets.length &&\n <>\n <BannerHeader\n type='partner-profile'\n partnerBannerType={ContentPartnersHelper.getPartnerBannerType(props.partnerProfile)}\n heading={bannerInfo.heading}\n blockColourClass={bannerInfo.blockColourClass}\n logo={bannerInfo.logo}\n logoBgColour={bannerInfo.logoBgColour}\n banner={bannerInfo.banner}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n actions={props.getBannerActions?.()}\n onClickSignUp={props.onClickSignUp}\n isAuthenticated={props.isAuthenticated}\n videoUrl={props.partnerProfile._videobanner?.value?.url}\n websiteUrl={ContentPartnersHelper.getPartnerLinkByType(\n props.partnerProfile?.links,\n 'website',\n ContentPartnersHelper.makeUTMs({ slug: props.partnerProfile._slug.value })\n )}\n isStudent={props.hasPermissions(PermissionName.StudentExperience)}\n log={props.log}\n />\n \n <div className='py-3 mb-3 border-bottom'>\n <Breadcrumbs breadcrumbs={props.breadcrumbs} />\n {showExpandableDescription && (\n <ChannelDashboardDescription partnerProfile={props.partnerProfile} />\n )}\n </div>\n\n <div className='mt-3'>\n {!emptyState && widgets.map((widget, idx) => (\n <InfiniteWidgetContainerView<CuratedWidget, CuratedWidget, AllPartnerProfileWidgetTemplates>\n dashboardTarget={DashboardTargetType.PartnerProfile}\n key={widget.id}\n index={idx}\n item={widget}\n infiniteFetch={shouldInfiniteFetch(widgets, idx)}\n getName={widget => widget.name}\n getWidgetMetadata={w => w.metadata}\n appLinks={props.widgetAppLinks}\n hasPermissions={props.hasPermissions}\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n setIsEmpty={isEmpty => setEmptyWidget(widget.id, isEmpty)}\n getCursor={w => w.cursor}\n getRequest={cursor => getWidgetContentRequest(widget.id, widget.widgetId, widget.templateId, cursor)}\n hasLocalPermissions={props.hasLocalPermissions}\n settingsHash={props.settings}\n getContent={w => w.content}\n resultsTransformers={WidgetHelper.getWidgetResultsTransformers()}\n onClickSearchAllVideos={props.onClickSearchAllVideos}\n getSeeMoreAppLink={props.getSeeMoreAppLink}\n isEmptyPredicate={items => (\n Array.isArray(items) && Array.isArray(items[0]?.content) && !items[0]?.content?.length\n )}\n\n getSelectedItems={null}\n appLinkOptions={null}\n />\n ))}\n </div>\n </>\n }\n\n {emptyState && <ContentPartnerEmptyState\n type={emptyState}\n // Coming soon empty state props\n partnerName={props.partnerProfile.name}\n comingSoonImageUrl={props.emptyImageUrl}\n // Content region empty state props\n contentRegionImageUrl={props.emptyImageUrl}\n contentRegionButtonLink={props.widgetAppLinks?.partnerHome?.()}\n // No content empty state props\n noContentImageUrl={props.emptyImageUrl}\n />}\n </>\n );\n}\n","@import '~styles/utils/include-media';\n:local{\n .pillTab {\n @include media('<=md') {\n li {\n min-width: 5rem;\n }\n }\n\n }\n}","import React from 'react';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { DashboardUserType } from 'libs/shared/interfaces';\n\nimport styles from './discover-header.module.scss';\n\nconst namespace = 'discover.header';\n\nexport interface DiscoverHeaderAppLinks {\n forYou: Core.AppLink;\n whatsNew: Core.AppLink;\n calendar: Core.AppLink;\n}\n\ninterface DiscoverHeaderProps {\n type: DashboardUserType;\n hasStudentExperience?: boolean;\n appLinks?: DiscoverHeaderAppLinks;\n showCalendar: boolean;\n active: keyof DiscoverHeaderAppLinks;\n isUpselling?: boolean;\n}\n\nexport function DiscoverHeader(props: DiscoverHeaderProps): JSX.Element {\n if (!props.type)\n return <></>;\n\n if (props.type === DashboardUserType.Learner || props.hasStudentExperience) {\n return (\n <div className='py-3'>\n <h1 className='h2 mb-0'>\n <Text namespace={namespace} phrase='heading' />\n </h1>\n </div>\n );\n }\n\n if (props.isUpselling)\n return <></>;\n\n const tabs = [{\n name: LanguageService.getPhrase(namespace, 'forYou'),\n appLink: props.appLinks?.forYou,\n active: props.active === 'forYou',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'forYou'),\n url: AppLinkHelper.getHref(props.appLinks?.forYou)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n }, {\n name: LanguageService.getPhrase(namespace, 'whatsNew'),\n appLink: props.appLinks?.whatsNew,\n active: props.active === 'whatsNew',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'whatsNew'),\n url: AppLinkHelper.getHref(props.appLinks?.whatsNew)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n },\n {\n name: LanguageService.getPhrase(namespace, 'calendar'),\n appLink: props.appLinks?.calendar,\n active: props.active === 'calendar',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'calendar'),\n url: AppLinkHelper.getHref(props.appLinks?.calendar)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n hide: !props.showCalendar\n }];\n\n return (\n <div className='py-3 text-center mx-n3'>\n <PillTabSelector\n tabs={tabs}\n className={styles.pillTab}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { FixedWidget } from 'libs/shared/components/widgets/fixed-widget';\nimport { VideoWidgetItemV2 } from 'libs/shared/components/widgets/items/video-widget-item/v2/VideoWidgetItemV2';\nimport { WidgetContents } from 'libs/shared/enums/WidgetContents';\nimport { PlaylistRequests } from 'libs/shared/flight-requests/PlaylistRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { CurrentUser, Following, PresentationAudience, Video, VideoTypes } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\n\nconst namespace = 'discover.tutorials';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface TutorialVideosContext {\n playlistId: string;\n videos?: VideoTypes[];\n shouldShowPanel: boolean;\n readyToShowPanel: boolean;\n shouldShowProductTip: boolean;\n dismissPanel?: () => void;\n appLink?: Core.AppLink;\n getVideoAppLink?: (child: Video) => Core.AppLink;\n}\n\ninterface TutorialVideoWidgetProps {\n commonVideoProps: CommonVideoProps;\n audiences: PresentationAudience[];\n context: TutorialVideosContext;\n}\n\nexport function TutorialVideoWidget(props: TutorialVideoWidgetProps) {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n \n const following = Flight.useBasicFetch<Following>(\n currentUser.data?.id &&\n PlaylistRequests.getIsFollowingPlaylist(props.context.playlistId, currentUser.data?.id)\n );\n\n const [ isFollowing, setIsFollowing ] = React.useState(null);\n const [ showSpinner, setShowSpinner ] = React.useState(false);\n const alerts = useAlerts();\n const fetchAsync = Flight.useGetFetchAsync();\n\n React.useEffect(() => {\n if (following.hasCompleted) {\n setIsFollowing(following.data?.isFollowing);\n }\n }, [following.data?.isFollowing]);\n\n const follow = async (shouldFollow: boolean) => {\n setShowSpinner(true);\n\n const req = shouldFollow ?\n PlaylistRequests.followPlaylist :\n PlaylistRequests.unfollowPlaylist;\n\n const error = () => {\n alerts.error(getPhrase(shouldFollow ? 'followError' : 'unfollowError'));\n setShowSpinner(false);\n };\n\n const success = () => {\n alerts.success(getPhrase(shouldFollow ? 'followSuccess' : 'unfollowSuccess'));\n setIsFollowing(shouldFollow);\n setShowSpinner(false);\n };\n\n await fetchAsync(req(props.context.playlistId, currentUser.data?.id, success, error));\n };\n \n return (\n <FixedWidget\n name={getPhrase('heading')}\n contents={WidgetContents.Videos}\n appLink={props.context.appLink}\n getChildAppLink={props.context.getVideoAppLink}\n collection={props.context.videos}\n childComponent={VideoWidgetItemV2}\n extraChildComponentProps={{\n commonVideoProps: props.commonVideoProps,\n presentationAudiences: props.audiences\n }}\n showSeeMoreLink={false}\n onClose={props.context.dismissPanel}\n onFollow={follow}\n isFollowing={isFollowing}\n showFollowSpinner={showSpinner}\n prefetched\n />\n );\n}\n","@import '~styles/utils/include-media';\n\n:local {\n .container {\n background-size: cover;\n }\n\n .eventLogo {\n width: 2.0625rem; //32px + 1px border\n height: 2.0625rem;\n }\n\n .cvLogoContainer {\n width: 2.0625rem;\n height: 2.0625rem;\n }\n\n .cvLogo {\n width: 0.625rem;\n // ClickView logo looks better when positioned slightly further to the right\n left: 53%;\n top: 50%;\n transform: translate(-50%, -50%);\n }\n\n .countdownGrid {\n display: grid;\n grid-template-columns: repeat(4, 1fr);\n gap: map-get($spacers, 1);\n\n @include media('<=md') {\n margin-top: map-get($spacers, 2);\n }\n }\n\n .timeBox {\n width: 4.3125rem;\n height: 4.3125rem;\n border: 0.125rem solid $light-blue;\n }\n\n .timeLabel {\n font-size: 0.75rem; //12px\n }\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AppLink as AppLinkComponent } from 'libs/shared/components/app-link/AppLink';\nimport { ClickViewPlayLogo } from 'libs/shared/components/svgs/clickview-logo/ClickViewLogo';\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport styles from './countdown.module.scss';\n\nconst timeUnitNamespace = 'shared.countdown';\n\ninterface TimeBoxProps {\n value: number;\n label: string;\n shouldFormat: boolean;\n}\n\nfunction formatNumber(num: number) {\n return num.toString().padStart(2, '0');\n}\n\nfunction TimeBox(props: TimeBoxProps) {\n return (\n <div className={`bg-white d-flex rounded-3 flex-column align-items-center justify-content-center p-1 ${styles.timeBox}`}>\n <div className='fs-5 h6 mb-0 flex-grow-1 align-content-center'>\n {props.shouldFormat ? formatNumber(props.value) : props.value}\n </div>\n <div className={styles.timeLabel}>{props.label}</div>\n </div>\n );\n}\n\nexport interface CountdownWidgetProps {\n targetDate: Date;\n endDate: Date;\n imageUrls: CountdownImageUrls;\n langNamespace: string;\n appLink?: AppLink;\n onCtaClick?: () => void;\n /** When true, the event has ended but is still shown (due to showDaysAfter). */\n hasEnded?: boolean;\n}\n\nexport function CountdownWidget(props: CountdownWidgetProps): JSX.Element | null {\n const [ timeLeft, setTimeLeft ] = React.useState({\n days: 0,\n hours: 0,\n minutes: 0,\n seconds: 0\n });\n const [ isEventEnded, setIsEventEnded ] = React.useState(false);\n const shouldShowLogos = props.imageUrls.logo;\n\n React.useEffect(() => {\n let timer: number = 0;\n\n const calculateTimeLeft = () => {\n const now = new Date().getTime();\n const targetTime = props.targetDate.getTime();\n const endTime = props.endDate.getTime();\n\n if (now >= endTime) {\n setIsEventEnded(true);\n clearInterval(timer);\n return;\n }\n\n const difference = targetTime - now;\n\n if (difference > 0) {\n setTimeLeft({\n days: Math.floor(difference / (1000 * 60 * 60 * 24)),\n hours: Math.floor((difference / (1000 * 60 * 60)) % 24),\n minutes: Math.floor((difference / 1000 / 60) % 60),\n seconds: Math.floor((difference / 1000) % 60)\n });\n } else {\n setTimeLeft({ days: 0, hours: 0, minutes: 0, seconds: 0 });\n clearInterval(timer);\n }\n };\n\n calculateTimeLeft();\n timer = window.setInterval(calculateTimeLeft, 1000);\n\n return () => clearInterval(timer);\n }, [ props.targetDate, props.endDate ]);\n\n if (isEventEnded && !props.hasEnded) {\n return null;\n }\n\n const timeUnits = [\n { value: timeLeft.days, label: LanguageService.getPhrase(timeUnitNamespace, 'days'), format: false },\n { value: timeLeft.hours, label: LanguageService.getPhrase(timeUnitNamespace, 'hours'), format: true },\n { value: timeLeft.minutes, label: LanguageService.getPhrase(timeUnitNamespace, 'minutes'), format: true },\n { value: timeLeft.seconds, label: LanguageService.getPhrase(timeUnitNamespace, 'seconds'), format: true }\n ];\n\n const isCountdownFinished = timeLeft.days === 0\n && timeLeft.hours === 0\n && timeLeft.minutes === 0\n && timeLeft.seconds === 0;\n\n return (\n <div\n className={`${styles.container} position-relative d-flex flex-md-row justify-content-md-between flex-column justify-content-center align-items-center p-3 mb-4 rounded`}\n style={{\n backgroundImage: `url('${props.imageUrls.background}')`\n }}\n >\n <div className='d-flex flex-column gap-2 align-items-md-start align-items-center w-md-auto w-100'>\n <div className='d-flex flex-md-row align-items-center flex-column gap-2'>\n {shouldShowLogos && (\n <ul className='list-unstyled d-flex mb-0'>\n <li className={`bg-white rounded-circle z-1 ${styles.eventLogo} border`}>\n <img src={props.imageUrls.logo} className='rounded-circle img-fluid' />\n </li>\n <li className={`bg-white rounded-circle position-relative ms-n1 ${styles.cvLogoContainer} border`}>\n <div className={`position-absolute d-flex align-items-center justify-content-center ${styles.cvLogo}`}>\n <ClickViewPlayLogo />\n </div>\n </li>\n </ul>\n )}\n <h2 className='h4 text-white text-shadow mb-0 lh-1 my-3 my-md-0'>\n {props.hasEnded ?\n LanguageService.getPhrase(props.langNamespace, 'titleAfter') :\n isCountdownFinished ?\n LanguageService.getPhrase(props.langNamespace, 'titleStarted') :\n LanguageService.getPhrase(props.langNamespace, 'title')}\n </h2>\n </div>\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit d-none d-md-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'cta')}\n </AppLinkComponent>\n }\n </div>\n\n {!isCountdownFinished &&\n <div className={styles.countdownGrid}>\n {timeUnits.map(unit => <TimeBox key={unit.label} {...unit} shouldFormat={unit.format} />)}\n </div>\n }\n\n {props.appLink &&\n <AppLinkComponent\n appLink={props.appLink}\n className='btn btn-outline-dark w-fit mt-3 d-md-none d-flex'\n onClick={props.onCtaClick}\n >\n {LanguageService.getPhrase(props.langNamespace, 'ctaMobile')}\n </AppLinkComponent>\n }\n </div>\n );\n}\n","import React from 'react';\n\nimport { AppLink } from 'libs/common/backbone/core';\n\nimport { CountdownImageUrls } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\n\nimport { CountdownWidget } from './CountdownWidget';\n\ninterface ImageUrlMap {\n [key: string]: ImageUrlMap | string;\n}\n\nexport interface CountdownExternalContext {\n // Map of image URL constants from the consuming project\n imageUrls: ImageUrlMap;\n getAppLink: (presentationId: string, eventTopicKey: string) => AppLink | null;\n}\n\ninterface ResolvedEventData {\n imageUrls: CountdownImageUrls | null;\n appLink?: AppLink | null;\n}\n\nexport interface CountdownEventConfig {\n key: string;\n // countdown will count towards this date\n targetDate: Date;\n // event is hidden after this date\n endDate: Date;\n langNamespace: string;\n allowedPresentationIds: string[];\n // key used to look up event topics in HardCoded (e.g. 'OlympicsTopics', 'CommonwealthGameTopics')\n eventTopicKey: string;\n getEventConfig: (presentationId: string, context: CountdownExternalContext) => ResolvedEventData;\n /** \n * Number of days before targetDate to start showing the countdown.\n * If not provided, the countdown is shown immediately (as long as now < endDate).\n * Make sure to set up phrase 'titleStarted' for your event.\n */\n showDaysBefore?: number;\n /**\n * Number of days after endDate to keep showing the countdown.\n * If not provided, the countdown is hidden immediately after endDate.\n * Make sure to set up phrase 'tittleAfter' for your event.\n */\n showDaysAfter?: number;\n}\n\ninterface CountdownContainerProps {\n presentationId: string;\n // List of countdown event configs, ordered by priority\n events: CountdownEventConfig[];\n // External context passed from the consuming component\n context: CountdownExternalContext;\n}\n\nfunction getActiveEvent(\n events: CountdownEventConfig[],\n presentationId: string\n): CountdownEventConfig | undefined {\n const now = new Date().getTime();\n\n return events.find(event => {\n if (!event.allowedPresentationIds.includes(presentationId)) {\n return false;\n }\n\n const effectiveEndDate = event.showDaysAfter !== undefined ?\n event.endDate.getTime() + event.showDaysAfter * 24 * 60 * 60 * 1000 :\n event.endDate.getTime();\n\n if (now >= effectiveEndDate) {\n return false;\n }\n\n if (event.showDaysBefore !== undefined) {\n const showFromDate = new Date(event.targetDate.getTime() - event.showDaysBefore * 24 * 60 * 60 * 1000);\n if (now < showFromDate.getTime()) {\n return false;\n }\n }\n\n return true;\n });\n}\n\nexport function CountdownContainer(props: CountdownContainerProps): JSX.Element | null {\n const activeEvent = getActiveEvent(props.events, props.presentationId);\n\n if (!activeEvent) {\n return null;\n }\n\n const config = activeEvent.getEventConfig(props.presentationId, props.context);\n\n if (!config.imageUrls) {\n return null;\n }\n\n const hasEnded = new Date().getTime() >= activeEvent.endDate.getTime();\n\n return (\n <CountdownWidget\n key={activeEvent.key}\n targetDate={activeEvent.targetDate}\n endDate={activeEvent.endDate}\n imageUrls={config.imageUrls}\n langNamespace={activeEvent.langNamespace}\n appLink={config.appLink}\n hasEnded={hasEnded}\n />\n );\n}\n","import { HardCoded } from 'libs/shared/constants/HardCoded';\n\nimport { CountdownEventConfig } from '../CountdownContainer';\n\nconst COMMONWEALTH_GAME_START_DATE_UTC = new Date('2026-07-23T00:00:00Z');\nconst COMMONWEALTH_GAME_END_DATE_UTC = new Date('2026-08-02T23:59:59Z');\n\nconst COMMONWEALTH_GAME_PRESENTATION_IDS = [\n HardCoded.PresentationIds.SCT_PRIMARY,\n HardCoded.PresentationIds.SCT_SECONDARY,\n HardCoded.PresentationIds.ENG_PRIMARY,\n HardCoded.PresentationIds.ENG_SECONDARY,\n HardCoded.PresentationIds.AU_PRIMARY,\n HardCoded.PresentationIds.AU_SECONDARY\n].map(id => id.toString());\n\nconst PRESENTATION_TO_IMAGE_KEY: Record<string, string> = {\n [HardCoded.PresentationIds.SCT_PRIMARY]: 'SCT_PRIMARY',\n [HardCoded.PresentationIds.SCT_SECONDARY]: 'SCT_SECONDARY',\n [HardCoded.PresentationIds.ENG_PRIMARY]: 'ENG_PRIMARY',\n [HardCoded.PresentationIds.ENG_SECONDARY]: 'ENG_SECONDARY',\n [HardCoded.PresentationIds.AU_PRIMARY]: 'AU_PRIMARY',\n [HardCoded.PresentationIds.AU_SECONDARY]: 'AU_SECONDARY'\n};\n\nexport const commonwealthGameCountdownEvent: CountdownEventConfig = {\n key: 'commonwealth-games-2026',\n targetDate: COMMONWEALTH_GAME_START_DATE_UTC,\n endDate: COMMONWEALTH_GAME_END_DATE_UTC,\n langNamespace: 'shared.commonwealthGameCountdown',\n allowedPresentationIds: COMMONWEALTH_GAME_PRESENTATION_IDS,\n eventTopicKey: 'CommonwealthGameTopics',\n // we want to show the event for 30 days before the start\n showDaysBefore: 30,\n // we want to show the event for 7 days after the end day\n showDaysAfter: 7,\n\n getEventConfig: (presentationId, context) => {\n const images = context.imageUrls.CommonwealthGamesCountdown as Record<string, string> | undefined;\n\n if (!images) {\n return { imageUrls: null };\n }\n\n const imageKey = PRESENTATION_TO_IMAGE_KEY[presentationId];\n const background = imageKey ? images[imageKey] as string : null;\n\n if (!background) {\n return { imageUrls: null };\n }\n\n const appLink = context.getAppLink(presentationId, 'CommonwealthGameTopics');\n\n return {\n // we don't show logos for this event\n imageUrls: { background },\n appLink\n };\n }\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.discoverDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface DiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function DiscoverDashboardEmptyState(props: DiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { DiscoverHeader, DiscoverHeaderAppLinks } from 'libs/shared/apps/discover/components/header/DiscoverHeader';\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { CountdownContainer, CountdownExternalContext } from 'libs/shared/components/widgets/countdown/CountdownContainer';\nimport { commonwealthGameCountdownEvent } from 'libs/shared/components/widgets/countdown/events/commonwealth-game';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience, WidgetPreference } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { DiscoverDashboardEmptyState } from './empty-state/DiscoverDashboardEmptyState';\n\nexport interface DiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation: Presentation\n ) => Flight.Request;\n audiences: PresentationAudience[];\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: DiscoverHeaderAppLinks;\n scrollToWidgetId?: string;\n updatePreferences?: (\n widgetId: string,\n widgetTypeId: WidgetTypeId,\n oldPreferences: WidgetPreference[],\n newPreferences: WidgetPreference[]\n ) => Promise<void>;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n removeFromVideoHistory: (videoId: string, videoName: string, widgetId: string, widgetTypeId: WidgetTypeId) => void;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n showCalendar: boolean;\n settings: SettingsHash;\n availablePresentations: Presentation[];\n isTertiaryCustomerWithoutExchange: boolean;\n commonVideoProps: CommonVideoProps;\n countdownContext?: CountdownExternalContext;\n tutorialVideosContext?: TutorialVideosContext;\n contentType?: CalendarEventContentType;\n isUpselling?: boolean;\n reminderComponent?: JSX.Element;\n}\n\nexport function DiscoverDashboard(props: DiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template, props.presentation);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <DiscoverHeader\n type={props.dashboard?.userType}\n appLinks={props.headerAppLinks}\n hasStudentExperience={props.hasPermissions(PermissionName.StudentExperience)}\n showCalendar={props.showCalendar}\n active='forYou'\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {props.countdownContext && props.presentation?.id && (\n <CountdownContainer\n presentationId={props.presentation.id.toString()}\n events={[commonwealthGameCountdownEvent]}\n context={props.countdownContext}\n />\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n preferences={widget.preferences}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n onSubmitFeedback={props.onSubmitFeedback}\n updatePreferences={props.updatePreferences}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n settings={{\n hasTopicDirectories: props.settings?.hasTopicDirectories\n }}\n availablePresentations={props.availablePresentations}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n settingsHash={props.settings}\n contentType={props.contentType}\n isUpselling={props.isUpselling}\n\n // TODO: Ideally we don't have to do this\n classification={undefined}\n hasTableOfContents={false}\n limitTotalItems={false}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n seeMoreLink={undefined}\n onClickRemoveItem={props.removeFromVideoHistory}\n badgeComponent={null}\n reminderComponent={props.reminderComponent}\n />\n );\n })}\n\n {showEmptyState && (\n <DiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'moviesAndTv.companyDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CompanyDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function CompanyDashboardEmptyState(props: CompanyDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { CompanyDashboardEmptyState } from 'libs/shared/apps/movies-and-tv/components/company-dashboard/empty-state/CompanyDashboardEmptyState';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader, PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllCompanyWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { Company, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nexport interface CompanyDashboardProps {\n dashboard: CuratedDashboard;\n company: Company;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n widgetAppLinks?: AllCompanyWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n getBreadcrumbs?: () => Breadcrumb[];\n getBannerActions?: () => ActionOptions[];\n commonVideoProps: CommonVideoProps;\n\n settings?: AllCompanyWidgetTemplates['settings'];\n}\n\nexport function CompanyDashboard(props: CompanyDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n {!!widgets.length &&\n <>\n {props.company ?\n (\n <BannerHeader\n heading={props.company.name}\n banner={props.company.banner}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n blockColourClass={getBgColorClass(props.company.name, BG_COLOUR_CLASS_NAMES)}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n />\n ) : <PartialBannerHeader />\n }\n\n <div className='py-3 mb-3 border-bottom'>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n </div>\n\n <div className='mt-3'>\n {widgets.map(widget => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Company}\n dashboardTarget={DashboardTargetType.Company}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n settings={props.settings}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n\n // TODO: Ideally we don't have to do this\n classification={null}\n contentType={null}\n hasTableOfContents={false}\n seeMoreLink={null}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n </div>\n </>\n }\n\n {showEmptyState && (\n <CompanyDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n",":local {\n .link {\n background-size: cover;\n background-position: 50% 50%;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { UseProductsResponse } from 'libs/shared/hooks/UseProducts';\nimport { NewWindowSvg } from 'libs/shared/images/svg/actions/NewWindowSvg';\nimport { ExchangeTvProductOption } from 'libs/shared/interfaces/ExchangeTvProductOption';\n\nimport styles from './exchange-and-tv-links.module.scss';\n\nconst namespace = 'moviesAndTV.exchangeAndTvLinks';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface LinkProps {\n backgroundImage: string;\n backgroundColor: string;\n title: string;\n cta: string;\n href: string;\n}\n\nfunction Link(props: LinkProps): JSX.Element {\n function onClick(): void {\n AnalyticsHelper.logUserAction({ href: props.href }, {\n actionType: UserAction.Click,\n entity: EntityType.Link,\n location: LocationContext.ExchangeLinksWidget\n });\n }\n\n const style: React.CSSProperties = {\n backgroundColor: props.backgroundColor\n };\n\n if (props.backgroundImage)\n style.backgroundImage = `url(${props.backgroundImage})`;\n\n return (\n <div\n className={`d-flex justify-content-between align-items-center text-white p-3 mb-3 rounded-3 ${styles.link}`}\n style={style}\n >\n <a className='h6 text-shadow mb-0' href={props.href} target='_blank' onClick={onClick}>{props.title}</a>\n <IconButton\n href={props.href}\n svg={NewWindowSvg}\n openInNewTab\n className='btn btn-outline-dark d-lg-block d-none'\n onClick={onClick}\n >\n {props.cta}\n </IconButton>\n </div>\n );\n}\n\ninterface ExchangeAndTvLinksProps {\n isPrimary: boolean;\n exchangeTvProductOption: ExchangeTvProductOption;\n products: UseProductsResponse;\n}\n\nexport function ExchangeAndTvLinks(props: ExchangeAndTvLinksProps): JSX.Element {\n const shouldShow = (\n !props.products.isLoadingProducts &&\n props.products.hasProduct(ProductId.Exchange) &&\n props.exchangeTvProductOption === 'exchange_and_tv'\n );\n\n if (!shouldShow)\n return <></>;\n\n const exchangeUrl = props.products.products.data.find(p => p.id === ProductId.Exchange).url;\n\n return (\n <div>\n <div className='curated-widget-header'>\n <h2 className='h4 curated-widget-heading'>\n <Text namespace={namespace} phrase='title' />\n </h2>\n </div>\n <div className='row'>\n <div className='col-md-6 col-12'>\n <Link\n title={getPhrase('exchangeText')}\n cta={getPhrase('exchangeCta')}\n backgroundColor='#7A76EB'\n backgroundImage={props.isPrimary ? '' : 'https://img.clickviewapp.com/v2/thumbnails/7mqa32'}\n href={exchangeUrl + '/exchange'}\n />\n </div>\n <div className='col-md-6 col-12'>\n <Link\n title={getPhrase('tvText')}\n cta={getPhrase('tvCta')}\n backgroundColor='#40BCC3'\n backgroundImage={props.isPrimary ? '' : 'https://img.clickviewapp.com/v2/thumbnails/Eo3L1k'}\n href={exchangeUrl + '/tv'}\n />\n </div>\n </div>\n </div>\n );\n}\n","import { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/flight';\n\nimport { BootstrapKeys } from 'libs/shared/constants/BootstrapKeys';\nimport { Product } from 'libs/shared/interfaces';\n\nexport const ProductRequests = {\n userProducts(\n success?: (data: Product[]) => void,\n error?: (xhr: Xhr) => void\n ): Flight.Request {\n return {\n url: '{gateway}/v1/users/me/products',\n key: 'user:products',\n normalizeOptions: {\n namespace: 'product'\n },\n success,\n error,\n bootstrapName: BootstrapKeys.PRODUCTS\n };\n }\n};\n","import { Flight } from 'libs/common/flight';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { ProductRequests } from 'libs/shared/flight-requests/ProductRequests';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { CurrentUser, Product } from 'libs/shared/interfaces';\n\nexport type HasProductFunc = (productId: ProductId) => boolean;\n\nexport interface UseProductsResponse {\n hasProduct: (product: ProductId) => boolean;\n products: Flight.Response<Product[]>;\n isLoadingProducts: boolean;\n}\n\nexport const useProducts = (): UseProductsResponse => {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const products = Flight.useBasicFetch<Product[]>(currentUser.data?.isAuthenticated && ProductRequests.userProducts());\n const isLoadingProducts = !products.hasCompleted;\n\n const hasProduct = (productId: ProductId) => {\n if (isLoadingProducts || products.hasError)\n return false;\n\n if (!products.data?.length)\n return false;\n\n return products.data.some(product => product.id === productId);\n };\n\n return {\n hasProduct,\n products,\n isLoadingProducts\n };\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'moviesAndTv.dashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface MoviesAndTvDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function MoviesAndTvDashboardEmptyState(props: MoviesAndTvDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n",":local {\n .icon {\n width: 2.875rem;\n height: 3.0625rem;\n background-size: cover;\n }\n .title {\n margin-top: 1rem;\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { ExchangeAndTvLinks } from 'libs/shared/apps/movies-and-tv/components/exchange-and-tv-links/ExchangeAndTvLinks';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllMoviesAndTvWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { PermissionName } from 'libs/shared/enums/PermissionName';\nimport { PresentationLearningLevel } from 'libs/shared/enums/PresentationLearningLevel';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { useProducts, UseProductsResponse } from 'libs/shared/hooks/UseProducts';\nimport { SettingsHash } from 'libs/shared/hooks/useSettings';\nimport { InfoSvg } from 'libs/shared/images/svg/status/InfoSvg';\nimport { CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { MoviesAndTvDashboardEmptyState } from './empty-state/MoviesAndTvDashboardEmptyState';\n\nimport styles from './movies-and-tv-dashboard.module.scss';\n\nconst namespace = 'moviesAndTv.dashboard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface MoviesAndDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n moviesAndTvIconUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllMoviesAndTvWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n showPreviewingTooltip?: boolean;\n settings?: SettingsHash;\n products?: UseProductsResponse;\n commonVideoProps: CommonVideoProps;\n}\n\nexport function MoviesAndTvDashboard(props: MoviesAndDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { hasProduct } = useProducts();\n\n // todo replace with backend filtering widgets by permissions and products\n const hasExchange = props.hasPermissions(PermissionName.Exchange) && hasProduct(ProductId.Exchange);\n const filteredWidgets = props.isReadonly ?\n // in Curator every widget is visible\n widgets :\n widgets.filter(w =>\n (w.templateId !== WidgetTemplate.HeroBannerSmall && w.widgetId !== WidgetTypeId.Blurb)\n || hasExchange);\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !filteredWidgets?.length;\n\n return (\n <div className='px-4'>\n <div className='d-flex align-items-center'>\n <div style={{ backgroundImage: `url(${props.moviesAndTvIconUrl})` }} className={`${styles.icon}`}></div>\n <h1 className={`h2 ${styles.title} d-inline-block me-2`}>\n <Text namespace={namespace} phrase='heading' />\n </h1>\n {props.showPreviewingTooltip &&\n <div className='pt-1'>\n <Tooltip title={getPhrase('tooltip')} spanHack>\n <SvgContainer svg={InfoSvg} />\n </Tooltip>\n </div>\n }\n </div>\n <hr className='mt-2'/>\n <ExchangeAndTvLinks\n exchangeTvProductOption={props.settings?.exchangeTvProductOption}\n products={props.products}\n isPrimary={+PresentationLearningLevel[props.presentation?.learningLevel] === PresentationLearningLevel.Level_1}\n />\n {filteredWidgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.MoviesAndTv}\n settingsHash={props.settings}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.MoviesAndTv}\n widgetIndex={idx}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n settings={{\n hasTopicDirectories: props.settings?.hasTopicDirectories\n }}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n // TODO: Ideally we don't have to do this\n classification={null}\n hasTableOfContents={false}\n isEditing={false}\n setIsEmpty={() => {}}\n seeMoreLink={undefined}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n\n {showEmptyState && (\n <MoviesAndTvDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'streamable.companyDashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamableCompanyDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadOnly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function StreamableCompanyDashboardEmptyState(props: StreamableCompanyDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('headingForStreamable')} />\n {!props.isReadOnly ? (\n <EmptyState.Heading>\n <Text phrase='headingForStreamable' />\n </EmptyState.Heading>\n ) : (\n <>\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='headingForCurator' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n\n",":local {\n $badge-base-height-md: 1.5rem; // 24px — original look\n $badge-base-height-lg: 2.375rem; // 38px — matches btn-lg\n\n .disabled {\n background-color: $gray-100;\n }\n\n .disabledHighlighted {\n background-color: lighten($info, 15%);\n }\n\n .badgeMd {\n height: $badge-base-height-md;\n margin-right: 0.25rem;\n }\n\n .badgeLg {\n height: $badge-base-height-lg;\n font-size: $font-size-lg;\n padding: 0 1rem;\n margin-right: 0.75rem;\n margin-bottom: 0.75rem;\n }\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 { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\nimport styles from './audience-item.module.scss';\n\nconst namespace = 'shared.audienceItem';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction lowerCaseToTitleCase(str: string): string {\n return str.split(' ').map((s: string) => s.charAt(0).toUpperCase() + s.substring(1)).join(' ');\n}\n\nfunction getColourClass(highlight: boolean, isDisabled: boolean): string {\n if (highlight) return isDisabled ? `${styles.disabledHighlighted} text-light` : 'bg-gray-900 text-light';\n if (isDisabled) return `${styles.disabled} text-secondary`;\n return 'bg-light';\n}\n\ntype AudienceItemSize = 'md' | 'lg';\n\ninterface AudienceItemProps {\n audience: PresentationAudience;\n highlight: boolean;\n setAudience?: (audience: PresentationAudience, highlight: boolean) => void;\n isDisabled?: boolean;\n extraClasses?: string;\n size?: AudienceItemSize;\n}\n\nAudienceItem.defaultProps = {\n extraClasses: '',\n size: 'md'\n};\n\nconst SIZE_CLASS_MAP: Record<AudienceItemSize, string> = {\n md: styles.badgeMd,\n lg: styles.badgeLg\n};\n\nexport function AudienceItem(props: AudienceItemProps): React.ReactElement {\n const { audience, highlight, setAudience, isDisabled, extraClasses, size } = props;\n\n const className = classNames(\n getColourClass(highlight, isDisabled),\n isDisabled ? 'cursor-default' : 'cursor-pointer',\n SIZE_CLASS_MAP[size],\n extraClasses,\n 'lh-1 rounded-pill d-inline-block user-select-none'\n );\n\n const onClick = () => {\n if (isDisabled || !FunctionHelper.isFunction(setAudience))\n return;\n\n setAudience(audience, !highlight);\n };\n\n return (\n <button\n type='button'\n className={className}\n onClick={onClick}\n role='checkbox'\n aria-checked={highlight}\n aria-label={`${getPhrase('ariaFilter')} ${audience.name}`}\n disabled={isDisabled}\n >\n {lowerCaseToTitleCase(audience.name)}\n </button>\n );\n}\n","import * as React from 'react';\n\nimport { StorageType } from 'libs/common/backbone/utils/LocalStorageHelper';\nimport { Core } from 'libs/common/core';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { AudienceItem } from 'libs/shared/apps/subjects/components/audience-item/AudienceItem';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { SharedViewModelKeys } from 'libs/shared/constants/SharedViewModelKeys';\nimport { PresentationAudience } from 'libs/shared/interfaces';\nimport { PartialLoadingHelper } from 'libs/shared/utils/PartialLoadingHelper';\n\nconst namespace = 'subjects.audienceFilter';\n\ninterface AudienceFilterProps {\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n disabled?: boolean;\n appLink: Core.AppLink;\n disablePersist?: boolean;\n tooltip?: string;\n}\n\nexport function AudienceFilter(props: AudienceFilterProps): React.ReactElement {\n const { audiences, activeAudiences, appLink } = props;\n\n const isDisabled = props.disabled || !appLink;\n\n const [ , setActiveAudiences ] = useViewModel<PresentationAudience[]>(\n SharedViewModelKeys.AUDIENCE_FILTER,\n undefined,\n { storage: StorageType.SessionStorage }\n );\n\n React.useEffect(() => {\n if (!props.disablePersist)\n setActiveAudiences(activeAudiences);\n }, [activeAudiences?.map(o => o.masterId).join(':')]);\n\n function onToggleAudience(audience: PresentationAudience, isSelected: boolean): void {\n if (isDisabled)\n return;\n\n const activeAudienceNames = isSelected ?\n [ ...(activeAudiences?.map(a => a.name) ?? []), audience.name ] :\n activeAudiences.map(a => a.name).filter(name => name !== audience.name);\n\n const getParams = () => {\n const otherParams = ObjectHelper.omit(appLink.params, ['a']);\n\n if (!activeAudienceNames.length)\n return otherParams;\n\n return Object.assign({}, otherParams, { a: activeAudienceNames });\n };\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params: getParams()\n }, { replace: true });\n }\n\n function onClickClearAudiences(): void {\n if (isDisabled)\n return;\n\n const params = ObjectHelper.omit(appLink.params, ['a']);\n\n Core.AppLinkHelper.trigger({\n ...appLink,\n params\n }, { replace: true });\n }\n\n if (!audiences || !audiences.length)\n return <></>;\n\n return (\n <Tooltip title={props.tooltip} spanHack>\n <div className='d-flex flex-wrap row-gap-2'>\n {audiences.map((a: PresentationAudience) => (\n <AudienceItem\n key={a.masterId}\n audience={a}\n highlight={!isDisabled && !!activeAudiences?.find(aa => aa.masterId === a.masterId)}\n setAudience={onToggleAudience}\n isDisabled={isDisabled}\n />\n ))}\n {(!isDisabled && !!activeAudiences && !!Object.keys(activeAudiences).length) && (\n <DivButton className='info-link d-inline-block ms-1' onClick={onClickClearAudiences}>\n <Text namespace={namespace} phrase='clear' />\n </DivButton>\n )}\n </div>\n </Tooltip>\n );\n}\n\nconst PARTIAL_AUDIENCES = PartialLoadingHelper.getPartialLoadingItems({ numItems: 6 });\n\nexport const PartialAudienceFilter = () => (\n <div className='d-flex flex-wrap row-gap-2'>\n {PARTIAL_AUDIENCES.map(({ width }, idx) => (\n <span\n key={idx}\n className='rounded-pill partial-loading-background me-1'\n dangerouslySetInnerHTML={{ __html: '&nbsp' }}\n style={{ width }}\n />\n ))}\n </div>\n);\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { LinkifyHelper } from 'libs/common/react/utils/LinkifyHelper';\n\nimport { EntityType, LocationContext } from 'libs/analytics/interfaces';\n\nimport { StreamableCompanyDashboardEmptyState } from 'libs/shared/apps/streamable-learning/components/company-dashboard/empty-state/StreamableCompanyDashboardEmptyState';\nimport { AudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader, PartialBannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { ExpandableQuestion } from 'libs/shared/components/expandable-question/ExpandableQuestion';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllCompanyWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { BG_COLOUR_CLASS_NAMES } from 'libs/shared/constants/ColourClassNames';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { CalendarEventContentType, Company, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { getBgColorClass } from 'libs/shared/utils/getBgColorClass';\n\nconst namespace = 'streamable.companyDashboard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport interface StreamableCompanyDashboardProps {\n dashboard: CuratedDashboard;\n company: Company;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n audiences?: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllCompanyWidgetTemplates['appLinks'] & {\n audience: () => Core.AppLink,\n widgetWizard: () => Core.AppLink\n };\n scrollToWidgetId?: string;\n isReadOnly?: boolean;\n getBreadcrumbs?: () => Breadcrumb[];\n getBannerActions?: () => ActionOptions[];\n isBot?: boolean;\n lazyLoad?: boolean;\n commonVideoProps: CommonVideoProps;\n}\n\nexport function StreamableCompanyDashboard(props: StreamableCompanyDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n \n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard),\n props.activeAudiences?.map(a => a.masterId)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const onSetIsEmpty = React.useCallback((widgetId: string, isEmpty: boolean) => {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n setEmptyWidgets(newEmptyState);\n }, [ emptyWidgets, widgets ]);\n\n function shouldShowEmptyState(): boolean {\n if (!widgets?.length)\n return true;\n\n return Object.values(emptyWidgets).every(state => !!state);\n }\n\n const showEmptyState = shouldShowEmptyState();\n\n return (\n <>\n {!!widgets.length &&\n <>\n {props.company ?\n (\n <BannerHeader\n heading={props.company.name}\n logo={props.company.logo}\n logoBgColour={props.company.metadata?.colour}\n alignLogoLeft={!!props.company.logo || !!props.company.cover}\n banner={props.company.banner}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n blockColourClass={getBgColorClass(props.company.name, BG_COLOUR_CLASS_NAMES)}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n />\n ) : <PartialBannerHeader />\n }\n\n <div className='d-flex flex-column row-gap-3 py-3 mb-3 border-bottom'>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n\n <AudienceFilter\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n disabled={props.isReadOnly}\n appLink={props.widgetAppLinks?.audience()}\n />\n </div>\n\n {props.company.description && (\n <div className='mb-5'>\n <ExpandableQuestion\n id={props.company?.id}\n question={getPhrase('aboutUs')}\n answer={LinkifyHelper.linkifyText(props.company.description)}\n isBot={props.isBot}\n analyticsOptions={{\n entity: EntityType.Company,\n location: LocationContext.Dashboard\n }}\n />\n </div>\n )}\n\n <div>\n {widgets.map(widget => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Company}\n dashboardTarget={DashboardTargetType.Company}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n setIsEmpty={onSetIsEmpty}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadOnly}\n lazyLoad={props.lazyLoad}\n contentType={CalendarEventContentType.Livestream}\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n\n // TODO: Ideally we don't have to do this\n classification={null}\n seeMoreLink={undefined}\n hasTableOfContents={false}\n onClickRemoveItem={undefined}\n settings={{\n hasTopicDirectories: false\n }}\n badgeComponent={null}\n />\n );\n })}\n </div>\n </>\n }\n\n {showEmptyState && (\n <StreamableCompanyDashboardEmptyState\n dashboard={props.dashboard}\n isReadOnly={props.isReadOnly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","@import '~styles/utils/include-media';\n:local{\n .pillTab {\n @include media('<=md') {\n li {\n min-width: 5rem;\n }\n }\n\n }\n}","import React from 'react';\n\nimport { AppLinkHelper } from 'libs/common/backbone/core';\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\n\nimport styles from './streamable-header.module.scss';\n\nconst namespace = 'streamable.header';\n\nexport interface StreamableHeaderAppLinks {\n discover: Core.AppLink;\n calendar?: Core.AppLink;\n partners: Core.AppLink;\n}\n\ninterface StreamableHeaderProps {\n appLinks?: StreamableHeaderAppLinks;\n active: keyof StreamableHeaderAppLinks;\n isUpselling?: boolean;\n}\n\nexport function StreamableHeader(props: StreamableHeaderProps): JSX.Element {\n if (props.isUpselling)\n return <></>;\n\n const tabs = [{\n name: LanguageService.getPhrase(namespace, 'heading'),\n appLink: props.appLinks?.discover,\n active: props.active === 'discover',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'heading'),\n url: AppLinkHelper.getHref(props.appLinks?.discover)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n }];\n\n if (props.appLinks?.calendar)\n tabs.push({\n name: LanguageService.getPhrase(namespace, 'livestreams'),\n appLink: props.appLinks?.calendar,\n active: props.active === 'calendar',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'livestreams'),\n url: AppLinkHelper.getHref(props.appLinks?.calendar)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n });\n\n tabs.push({\n name: LanguageService.getPhrase(namespace, 'partners'),\n appLink: props.appLinks?.partners,\n active: props.active === 'partners',\n analyticsData: {\n name: LanguageService.getPhrase(namespace, 'partners'),\n url: AppLinkHelper.getHref(props.appLinks?.partners)\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n }\n });\n\n return (\n <div className='py-3 text-center'>\n <PillTabSelector\n tabs={tabs}\n className={styles.pillTab}\n />\n </div>\n );\n}\n","import { DevError } from 'libs/common/backbone/errors/DevError';\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { GatedPermission, LocalPermissionName, LocalPermissionsLookup, PermissionName, PermissionsLookup } from 'libs/shared/enums/PermissionName';\nimport { UserRequests } from 'libs/shared/flight-requests/UserRequests';\nimport { useAccessPolicy } from 'libs/shared/hooks/useAccessPolicy';\nimport { CurrentUser } from 'libs/shared/interfaces';\n\nimport { SharedViewModelKeys } from '../constants/SharedViewModelKeys';\n\nexport type HasPermissionsFunc = (filters: PermissionName | PermissionName[], type?: 'ALL' | 'ANY') => boolean;\nexport type HasLocalPermissionsFunc = (filters: LocalPermissionName | LocalPermissionName[]) => boolean;\n\n/**\n * Hidden - Don't see the feature at all\n * Hard gate - See the feature, but can't use it\n * Soft gate - See the feature, but can use it. UI should show it's a premium feature\n * Visible - See the feature and can use it\n * \n * - Sha\n */\nexport type GetGatedPermissionFunc = (name: PermissionName) => GatedPermission;\n\nfunction permissionCheck(permissions: PermissionsLookup, filters: PermissionName[], type?: 'ALL' | 'ANY'): boolean {\n if (!type)\n return !filters.find(p => !permissions[p]);\n\n if (type === 'ALL')\n return filters.every(p => permissions[p]);\n\n return filters.some(p => permissions[p]);\n}\n\nexport const usePermissions = () => {\n const currentUser = Flight.useBasicFetch<CurrentUser>(UserRequests.currentUser());\n const permissions = Flight.useBasicFetch<PermissionsLookup>(\n currentUser.hasCompleted &&\n UserRequests.permissions()\n );\n \n const { gatedPermissions } = useAccessPolicy();\n\n const [localPermissions] = useViewModel<LocalPermissionsLookup>(SharedViewModelKeys.LOCAL_PERMISSIONS);\n\n const hasPermissions: HasPermissionsFunc = (\n filters: PermissionName | PermissionName[],\n type?: 'ALL' | 'ANY'\n ) => {\n if (!permissions.hasCompleted || permissions.hasError)\n return false;\n\n if (!filters || !filters?.length)\n return true;\n\n if (!Array.isArray(filters))\n return !!permissions.data[filters];\n\n return permissionCheck(permissions.data, filters, type);\n };\n\n /**\n * Construct an enriched permission set object that contains server-side managed permissions\n * alongside local ones. I'm sure this will lead to further debate :joy:, but this\n * provides a mechanism to create locally derived permissions where the underlying data governing\n * it can be changed transparently. \n * \n * TODO (public): Review this approach prior to rolling out to prod. If we proceed, we can \n * DRY up this code a bit more.\n */\n const hasLocalPermissions: HasLocalPermissionsFunc = (\n filters: LocalPermissionName | LocalPermissionName[]\n ) => {\n if (!localPermissions)\n Core.ErrorHelper.throw(new DevError('Local Permissions should be registered during start up.'));\n\n if (!filters || !filters?.length)\n return true;\n\n if (!Array.isArray(filters))\n return !!localPermissions[filters];\n\n return !filters.find(p => !localPermissions[p]);\n };\n\n const getGatedPermission: GetGatedPermissionFunc = (\n name: PermissionName\n ) => {\n if (!permissions.hasCompleted || permissions.hasError)\n return 'hidden';\n\n if (!gatedPermissions.has(name))\n return permissions.data[name] ? 'visible' : 'hidden';\n\n return permissions.data[name] ? 'soft-gate' : 'hard-gate';\n };\n\n return {\n permissions: permissions.data,\n hasPermissions,\n hasLocalPermissions,\n getGatedPermission,\n isLoaded: permissions.hasCompleted\n };\n};\n\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'streamable.dashboardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface StreamableDiscoverDashboardEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function StreamableDiscoverDashboardEmptyState(props: StreamableDiscoverDashboardEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('info')} />\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { TutorialVideosContext, TutorialVideoWidget } from 'libs/shared/apps/discover/components/tutorial-videos/TutorialVideoWidget';\nimport { StreamableHeader, StreamableHeaderAppLinks } from 'libs/shared/apps/streamable-learning/components/header/StreamableHeader';\nimport { PartialPopoutThumbnailSlidingListSmallWidgetTemplate } from 'libs/shared/components/widgets/curated-widgets/templates/popout_thumbnail_sliding_list_small/partial-loading/PartialPopoutThumbnailSlidingListSmall';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllDiscoverWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { usePermissions } from 'libs/shared/hooks/usePermissions';\nimport { CalendarEventContentType, CuratedDashboard, CuratedWidgetQueryParams, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { StreamableDiscoverDashboardEmptyState } from './empty-state/StreamableDiscoverDashboardEmptyState';\n\nexport interface StreamableDiscoverDashboardProps {\n dashboard: CuratedDashboard;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n presentation: Presentation;\n widgetAppLinks?: AllDiscoverWidgetTemplates['appLinks'] & {\n widgetWizard: () => Core.AppLink\n };\n headerAppLinks?: StreamableHeaderAppLinks;\n scrollToWidgetId?: string;\n isReadonly?: boolean;\n lazyLoad?: boolean;\n commonVideoProps: CommonVideoProps;\n tutorialVideosContext?: TutorialVideosContext;\n isUpselling?: boolean;\n}\n\nexport function StreamableDiscoverDashboard(props: StreamableDiscoverDashboardProps): JSX.Element {\n const widgets = ArrayHelper.sortBy(props.dashboard?.widgets, 'index');\n\n const { hasPermissions, hasLocalPermissions } = usePermissions();\n\n function getWidgetContentRequest(id: string, widgetTypeId: WidgetTypeId, template: WidgetTemplate): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard)\n );\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = props.isReadonly && !widgets?.length;\n\n return (\n <>\n <StreamableHeader\n active='discover'\n appLinks={props.headerAppLinks}\n isUpselling={props.isUpselling}\n />\n\n {props.tutorialVideosContext?.shouldShowPanel && (\n <div className='curated-widget rounded-3 mb-3 mx-n4 px-4 py-3 overflow-hidden'>\n {\n props.tutorialVideosContext.readyToShowPanel ?\n <TutorialVideoWidget\n commonVideoProps={props.commonVideoProps}\n audiences={props.audiences}\n context={props.tutorialVideosContext}\n /> :\n <PartialPopoutThumbnailSlidingListSmallWidgetTemplate\n hideDescription\n />\n }\n </div>\n )}\n\n {widgets.map((widget, idx) => {\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Discover}\n key={widget.id}\n id={widget.id}\n getContentRequest={getWidgetContentRequest}\n audiences={props.audiences}\n name={widget.name}\n description={widget.description}\n templateId={widget.templateId}\n metadata={widget.metadata}\n presentation={props.presentation}\n appLinks={props.widgetAppLinks}\n isScrollToTargetWidget={props?.scrollToWidgetId === widget.id}\n widgetTypeId={widget.widgetId}\n lazyLoad={props.lazyLoad}\n dashboardTarget={DashboardTargetType.Discover}\n widgetIndex={idx}\n isPreviewing={props.isReadonly}\n contentType={CalendarEventContentType.Livestream}\n preferences={widget.preferences}\n hasPermissions={hasPermissions}\n hasLocalPermissions={hasLocalPermissions}\n isTertiaryCustomerWithoutExchange={false}\n preventPopout\n imageCdnUrl={props.commonVideoProps.imageCdnUrl}\n commonVideoProps={props.commonVideoProps}\n isUpselling={props.isUpselling}\n\n availablePresentations={undefined}\n classification={undefined}\n hasTableOfContents={undefined}\n onSubmitFeedback={undefined}\n settings={undefined}\n updatePreferences={undefined}\n seeMoreLink={undefined}\n onClickRemoveItem={undefined}\n badgeComponent={undefined}\n\n />\n );\n })}\n\n {showEmptyState && (\n <StreamableDiscoverDashboardEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.widgetAppLinks.widgetWizard}\n />\n )}\n </>\n );\n}\n","import React from 'react';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { Classification } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nconst namespace = 'subject.classificationHeaderDetails';\n\nconst Separator = ({ className }: { className: string }) =>\n <span className={className}>&bull;</span>;\n\ninterface ClassificationHeaderDetailsProps {\n classification: Classification;\n}\n\nexport function ClassificationHeaderDetails(props: ClassificationHeaderDetailsProps): React.ReactElement {\n const {\n dashboardVideoCount,\n childDashboardVideoCount,\n dashboardResourceCount,\n childDashboardResourceCount,\n childClassificationCount\n } = TopicsHelper.getCounts(props.classification);\n\n const videoCount = dashboardVideoCount + childDashboardVideoCount;\n const resourceCount = dashboardResourceCount + childDashboardResourceCount;\n\n return (\n <p className='mb-n1 font-size-normal fw-normal mt-1'>\n {!!childClassificationCount && (\n <Text\n namespace={namespace}\n phrase='topics'\n options={{ count: childClassificationCount.toLocaleString(), smartCount: childClassificationCount }}\n />\n )}\n\n {!!videoCount && (\n <>\n {childClassificationCount > 0 && <Separator className='mx-2' />}\n <Text\n namespace={namespace}\n phrase='videos'\n options={{ count: videoCount.toLocaleString(), smartCount: videoCount }}\n />\n </>\n )}\n {!!resourceCount && (\n <>\n <Separator className='mx-2' />\n <Text\n namespace={namespace}\n phrase='resources'\n options={{ count: resourceCount.toLocaleString(), smartCount: resourceCount }}\n />\n </>\n )}\n </p>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, DashboardStatus } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.curatedClassificationEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface CuratedClassificationEmptyStateProps {\n dashboard: CuratedDashboard;\n imageUrl: string;\n isReadonly: boolean;\n addWidgetApplink?: () => Core.AppLink;\n}\n\nexport function CuratedClassificationEmptyState(props: CuratedClassificationEmptyStateProps): JSX.Element {\n const isArchived = props.dashboard?.status === DashboardStatus.Archived;\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('headingForNP')} />\n {!props.isReadonly ? (\n <EmptyState.Heading>\n <Text phrase='headingForNP' />\n </EmptyState.Heading>\n ) : (\n <>\n <EmptyState.Heading>\n <Text namespace={namespace} phrase='headingForCurator' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text namespace={namespace} phrase='info' />\n </EmptyState.Info>\n <Tooltip title={isArchived ? LanguageService.getPhrase(namespace, 'archivedCtaTooltip') : ''} spanHack>\n <EmptyState.Cta\n text={LanguageService.getPhrase(namespace, 'add')}\n appLink={props.addWidgetApplink?.()}\n className='btn btn-dark'\n icon={PlusSvg}\n disabled={isArchived}\n />\n </Tooltip>\n </>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n",":local{\n $dot-size: 0.75rem;\n $track-offset: -1rem;\n\n @mixin dot {\n &::before {\n position: absolute;\n left: -1.06rem;\n top: calc(50% - $dot-size/2);\n display: block;\n content: '';\n height: $dot-size;\n width: $dot-size;\n border-radius: 50%;\n background-color: $black;\n }\n }\n\n @mixin tocIndent($depth) {\n margin-left: map-get($spacers, 3) * $depth;\n }\n \n .itemsWrapper {\n border-left: 2px solid $black;\n padding-left: 0.625rem;\n }\n\n .anchorWrapper {\n padding: 0.625rem;\n text-decoration: none;\n position: relative;\n display: block;\n }\n .anchorWrapper:hover {\n background-color: $light-blue;\n text-decoration: none;\n cursor: pointer;\n }\n\n .anchorWrapper:first-child {\n &::after {\n display: block;\n content: '';\n background-color: $white;\n height: calc(50% - $dot-size/2 + 0.05rem);\n width: 0.625rem;\n top: -0.05rem;\n position: absolute;\n left: $track-offset;\n }\n }\n .anchorWrapper:last-child {\n &::after {\n display: block;\n content: '';\n background-color: $white;\n height: calc(50% - $dot-size/2);\n width: 0.625rem;\n position: absolute;\n bottom: 0;\n left: $track-offset;\n }\n }\n\n .default {\n @include dot\n }\n\n .selectedItem {\n background-color: $gray-100;\n font-weight: 500;\n @include dot\n }\n \n .disabled:hover {\n cursor: default;\n background-color: $white;\n }\n .disabled{\n pointer-events:none\n }\n\n .floatIcon {\n position: absolute;\n right: 0;\n width: fit-content;\n padding: 0;\n .arrowIcon {\n display: none;\n }\n .listIcon {\n display: block;\n }\n &:hover {\n .listIcon {\n display: none;\n }\n .arrowIcon {\n display: block;\n }\n }\n }\n\n .tocIndent1 {\n @include tocIndent(1);\n }\n\n .tocIndent2 {\n @include tocIndent(2);\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { ScrollHelper } from 'libs/common/backbone/utils/ScrollHelper';\n\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { DivButton } from 'libs/shared/components/div-button/DivButton';\n\nimport styles from './table-of-contents-list.module.scss';\n\nexport interface TableOfContentsItem<T=string> {\n name: string;\n id: T;\n tocIndentation?: number;\n}\n\ninterface TableOfContentsProps<T> {\n items: TableOfContentsItem<T>[];\n activeId: string;\n appLink?: Core.AppLink;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n // set to true if the TOC is controlled by a local state rather than query params\n localState?: boolean;\n getAppLink?: (args: TableOfContentsItem<T>) => Core.AppLink;\n onItemClick?: (args: TableOfContentsItem<T>) => void;\n}\n\nexport function TableOfContentsList<T extends string>(props: TableOfContentsProps<T>): JSX.Element {\n const analyticsOptions = {\n actionType: UserAction.Click,\n entity: EntityType.Widget,\n location: LocationContext.TableOfContents\n };\n\n function onItemSelect(item: TableOfContentsItem<T>) {\n ScrollHelper.preventScrollTop();\n props.setControlledId(item.id);\n \n props.onItemClick?.(item);\n \n setTimeout(() => document.getElementById(item.id)?.focus());\n }\n\n function getTocIndentClass(item: TableOfContentsItem<T>): string {\n if (item.tocIndentation === 1)\n return styles.tocIndent1;\n \n if (item.tocIndentation === 2)\n return styles.tocIndent2;\n\n return '';\n }\n\n return (\n <div className={`${styles.itemsWrapper}`}>\n {props.items.map((item, idx) => {\n if (props.localState) {\n return (\n <DivButton\n key={item.id}\n className={`${styles.anchorWrapper} ${props.activeId === item.id ? styles.selectedItem : ''}`}\n onClick={() => {\n onItemSelect(item);\n }}\n >\n <div className={`${!props.activeId && idx === 0 ? styles.default : ''} `}>\n {item.name}\n </div>\n </DivButton>\n );\n }\n\n return (\n <AppLink\n key={item.id}\n appLink={props.getAppLink(item)}\n appLinkOptions={{ replace: true }}\n className={`${styles.anchorWrapper} ${props.activeId === item.id ? styles.selectedItem : ''}`}\n onClick={() => {\n onItemSelect(item);\n }}\n analyticsData={{\n ...props.analyticsData,\n id: item.id,\n name: item.name\n }}\n analyticsOptions={analyticsOptions}\n >\n <div className={`${!props.activeId && idx === 0 ? styles.default : ''} ${getTocIndentClass(item)}`}>\n {item.name}\n </div>\n </AppLink>\n );\n })}\n </div>\n );\n}\n","import React from 'react';\n\nexport function TableOfContentsSvg(props: React.SVGProps<SVGSVGElement>) {\n return (\n <svg {...props}>\n <path\n fill='currentColor'\n fillRule='evenodd'\n d='M5.5 8a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3m4-2a.5.5 0 0 0 0 1h10a.5.5 0 0 0 0-1zM9 11.5a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1h-10a.5.5 0 0 1-.5-.5M5.5 13a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3M9 16.5a.5.5 0 0 1 .5-.5h10a.5.5 0 0 1 0 1h-10a.5.5 0 0 1-.5-.5M5.5 18a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3'\n clipRule='evenodd'\n />\n </svg>\n );\n}\n","$top-nav-height: 4.1875rem;\n$cv-banner-height: calc(100vw * 22 / 120);\n$filters-area: 7.87rem;\n\n.container {\n position: sticky;\n top: 6.25rem;\n z-index: 80;\n}\n\n.mobile {\n position: fixed;\n top: calc($top-nav-height + $cv-banner-height + $filters-area);\n z-index: 80;\n right: 0;\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { AnalyticsHelper } from 'libs/analytics/AnalyticsHelper';\nimport { EntityType, HashObject, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { TableOfContentsList } from 'libs/shared/components/table-of-contents-list/TableOfContentsList';\nimport { TableOfContentsSvg } from 'libs/shared/images/svg/objects/TableOfContentsSvg';\nimport { CuratedWidget } from 'libs/shared/interfaces';\nimport { ContextService } from 'libs/shared/services/ContextService';\n\nimport styles from './table-of-contents.module.scss';\n\ninterface TableOfContentsContainerProps {\n widgets: CuratedWidget[];\n title: string;\n activeId: string;\n appLink?: Core.AppLink;\n clickable?: boolean;\n analyticsData?: HashObject;\n setControlledId: (arg: string) => void;\n isSmallScreen?: boolean;\n}\ninterface TableOfContentsProps extends TableOfContentsContainerProps {\n getAppLink: (widget: CuratedWidget) => Core.AppLink;\n}\n\nfunction TableOfContentsMobile(props: TableOfContentsProps) {\n const [ isExpanded, setIsExpanded ] = React.useState(false);\n\n function logUserAction() {\n const analyticsOptions = {\n actionType: !isExpanded ? UserAction.Open : UserAction.Hide,\n entity: EntityType.TableOfContents,\n location: LocationContext.Dashboard\n };\n\n AnalyticsHelper.logUserAction(props.analyticsData, analyticsOptions);\n }\n\n function onClickIcon() {\n setIsExpanded(!isExpanded);\n logUserAction();\n }\n\n return (\n <div className={`${styles.mobile} d-inline-flex gap-1`}>\n \n {isExpanded && (\n <div className='bg-white px-3 pt-3 pb-2 border border-dark rounded-1 ps-3'>\n <h2 className='h5'>{props.title}</h2>\n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n onItemClick={() => setIsExpanded(false)}\n />\n </div>\n )}\n <div className={styles.container}>\n <IconButton\n className='btn btn-outline-dark'\n svg={TableOfContentsSvg}\n onClick={onClickIcon}\n />\n </div>\n </div>\n );\n}\n\nfunction TableOfContents(props: TableOfContentsProps): JSX.Element {\n return (\n <aside className='col-3 order-1'>\n <div className={`${styles.container} ps-3`}>\n <h2 className='h5'>{props.title}</h2>\n \n <TableOfContentsList\n items={props.widgets.map(widget => (\n { name: widget.name, id: widget.id, tocIndentation: widget.metadata.tocIndentation }\n ))}\n activeId={props.activeId}\n appLink={props.appLink}\n analyticsData={props.analyticsData}\n setControlledId={props.setControlledId}\n getAppLink={props.getAppLink}\n />\n </div>\n </aside>\n );\n}\n\nexport function TableOfContentsContainer(props: TableOfContentsContainerProps): JSX.Element {\n function getAppLink(widget: CuratedWidget): Core.AppLink {\n const currentAppLink = ContextService.getCurrentRoute().appLink;\n \n const params: HashObject = currentAppLink.params ?\n { ...(currentAppLink.params as HashObject) } :\n {};\n\n params.tocId = widget.id;\n\n return {\n ...currentAppLink,\n params\n };\n }\n\n return (\n <>\n {!props.isSmallScreen ?\n <TableOfContents {...props} getAppLink={getAppLink} /> :\n <TableOfContentsMobile {...props} getAppLink={getAppLink} />\n }\n </>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Core } from 'libs/common/core';\n\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'subjects.teacherOnlyEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface TeacherOnlyEmptyStateProps {\n imageUrl: string;\n ctaAppLink?: () => Core.AppLink;\n}\n\nexport function TeacherOnlyEmptyState(props: TeacherOnlyEmptyStateProps): JSX.Element {\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('heading')} />\n <EmptyState.Heading>\n <Text phrase='heading' />\n </EmptyState.Heading>\n <EmptyState.Info>\n <Text phrase='info' />\n </EmptyState.Info>\n\n <EmptyState.Cta\n text={getPhrase('cta')}\n appLink={props.ctaAppLink?.()}\n className='btn btn-dark'\n />\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { HashObject } from 'libs/common/react/interfaces';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { CuratedDashboard, CuratedDashboardCollection, CuratedWidget, CuratedWidgetContent, CuratedWidgetQueryParams, CurrentUser, DashboardStatus, DashboardUserType, Presentation, WidgetPreference } from 'libs/shared/interfaces';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { HardCoded } from '../constants/HardCoded';\nimport { ContentRegion } from '../enums/ContentRegion';\nimport { WidgetTemplate } from '../enums/WidgetTemplate';\nimport { MasterTypeHelper } from '../utils/MasterTypeHelper';\nimport { ThemeAssetHelper } from '../utils/ThemeAssetHelper';\n\ninterface GetDashboardWidgetContentOptions {\n hideTigTag?: boolean;\n hideTwig?: boolean;\n cursor?: string;\n}\n\nconst TWIG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Twig.EnglandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.InternationalSecondary),\n ...Object.values(HardCoded.Classifications.Twig.ScotlandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.NewZealandSecondary),\n ...Object.values(HardCoded.Classifications.Twig.CanadaMiddle),\n ...Object.values(HardCoded.Classifications.Twig.CanadaHigh)\n]);\n\nconst TIG_TAG_TOPIC_IDS = new Set([\n ...Object.values(HardCoded.Classifications.Tigtag.EnglandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.InternationalPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.ScotlandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.NewZealandPrimary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaElementary),\n ...Object.values(HardCoded.Classifications.Tigtag.CanadaMiddle)\n]);\n\nfunction getQueryParamsKey(queryParams: CuratedWidgetQueryParams): string {\n return Object.keys(queryParams)\n .map((key: keyof CuratedWidgetQueryParams) => queryParams[key])\n .join(':');\n}\n\nfunction getNamespaceKey(queryParams: CuratedWidgetQueryParams, options: GetDashboardWidgetContentOptions): string {\n if (!options.cursor)\n return getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]));\n\n return `${getQueryParamsKey(ObjectHelper.pick(queryParams, [ 'audienceId', 'letterPrefix', 'sort' ]))}:${options.cursor}`;\n}\n\nfunction shouldNormalizeWidgetRequest(\n template: WidgetTemplate\n): boolean {\n if (template === WidgetTemplate.EditableCoverFixedPillListSmall)\n return false;\n\n return true;\n}\n\nexport const DashboardRequests = {\n classificationDashboard(\n classificationId: string,\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n dashboardId?: string | null\n ): Flight.PublicRequest {\n const queryParamOpts = {\n target: `classification:${classificationId}`,\n status: statuses,\n userType\n };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n key: `classification:dashboard:${classificationId}:${userType}:${dashboardId}:${statuses?.join(':')}`,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n }\n };\n },\n\n dashboardWidgetContent(\n id: string,\n queryParams: CuratedWidgetQueryParams = {},\n template?: WidgetTemplate,\n presentation?: Presentation,\n options: GetDashboardWidgetContentOptions = {}\n ): Flight.PublicRequest {\n const queryParamsWithCursor = { ...queryParams, cursor: options.cursor };\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/widgets/${id}`, queryParamsWithCursor),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/widgets/${id}`, queryParamsWithCursor),\n regionScoped: true,\n key: `widget:${id}:${getQueryParamsKey(queryParamsWithCursor)}`,\n formatData: (widget: CuratedWidget) => {\n const formatted = WidgetHelper.formatResponseData(widget, presentation);\n\n if (Array.isArray(formatted.content)) {\n formatted.content = formatted.content.map(\n entity => MasterTypeHelper.isClassification(entity) ?\n ThemeAssetHelper.applyThemeToClassification(entity) :\n entity\n ) as CuratedWidgetContent;\n }\n\n if (!options.hideTigTag && !options.hideTwig)\n return formatted;\n\n // Filter out the Twig topics for users who don't have access to the Twig library\n if (Array.isArray(formatted.content)) {\n const newContent = formatted.content.filter(entity => {\n if (MasterTypeHelper.isClassification(entity)) {\n if (TIG_TAG_TOPIC_IDS.has(entity.id))\n return !options.hideTigTag;\n\n if (TWIG_TOPIC_IDS.has(entity.id))\n return !options.hideTwig;\n\n return true;\n }\n \n return true;\n }) as CuratedWidgetContent;\n \n formatted.content = newContent;\n }\n \n return formatted;\n },\n normalizeOptions: {\n namespace: getNamespaceKey(queryParams, options)\n },\n normalize: shouldNormalizeWidgetRequest(template)\n };\n },\n\n getDashboard(\n userType: DashboardUserType,\n statuses: DashboardStatus[],\n target: string,\n curriculumIds?: string[],\n dashboardId?: string,\n contentRegion?: ContentRegion,\n success?: (data: CuratedDashboard) => void\n ): Flight.PublicRequest {\n const queryParamOpts: HashObject = {\n target,\n status: statuses,\n userType\n };\n\n if (curriculumIds?.length)\n queryParamOpts['widgets.curriculum'] = curriculumIds;\n\n if (contentRegion)\n queryParamOpts.contentRegion = contentRegion;\n\n const key = `dashboard:${target}:${userType}:${dashboardId}:${statuses.join(':')}:${contentRegion ?? ''}`;\n\n return {\n url: UrlHelper.urlBuilder(`{gateway}/v1/discover/dashboards`, queryParamOpts),\n publicUrl: UrlHelper.urlBuilder(`/api/discover/dashboards`, queryParamOpts),\n regionScoped: true,\n key,\n formatData: (data: CuratedDashboardCollection) => {\n if (dashboardId)\n return data.data?.find(d => d.id.toString() === dashboardId.toString());\n\n // only the first one of available dashboard will be displayed for the user\n return ArrayHelper.first(data.data);\n },\n success\n };\n },\n\n updateWidgetPreferences(widgetId: string, preferences: WidgetPreference[], currentUser: CurrentUser): Flight.Request {\n return {\n url: `{gateway}/v1/discover/widgets/${widgetId}/preferences`,\n key: 'update:widget:preferences',\n invalidationKeys: [`widget:${widgetId}`],\n type: HttpVerbs.PUT,\n data: {\n userId: currentUser.id,\n customerId: currentUser.customerId,\n metadata: preferences\n }\n };\n }\n};\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { DashboardRequests } from 'libs/shared/flight-requests/DashboardRequests';\nimport { CuratedDashboard, CuratedMediaWidget, CuratedWidget, PresentationAudience, Video } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nexport interface Response {\n widgets: CuratedWidget[];\n\n videoList?: Video[];\n videoListWidgetId?: string;\n}\n\n/**\n * This hook helps us with custom logic for to display system generated dashboards in a slightly\n * different way.\n */\nexport function useGetTopicsWidgets(dashboard: CuratedDashboard, activeAudiences: PresentationAudience[]): Response {\n const {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget\n } = React.useMemo(() => {\n if (!dashboard) {\n return {\n isSystemGeneratedDashboard: false,\n systemGeneratedVideoWidget: null\n };\n }\n\n const isSystemGeneratedDashboard = CuratedDashboardHelper.isSystemGeneratedDashboard(dashboard.widgets);\n\n return {\n isSystemGeneratedDashboard,\n systemGeneratedVideoWidget: dashboard.widgets.find(widget => {\n return (\n widget.widgetId === WidgetTypeId.ClassificationPinnedVideos &&\n widget.templateId !== WidgetTemplate.ThumbnailVerticalList\n );\n })\n };\n }, [dashboard?.id]);\n\n const systemGeneratedVideoContent = Flight.useBasicFetch<CuratedMediaWidget<Video[]>>(\n !!systemGeneratedVideoWidget &&\n DashboardRequests.dashboardWidgetContent(\n systemGeneratedVideoWidget?.id,\n CuratedDashboardHelper.getWidgetParams(\n systemGeneratedVideoWidget.widgetId,\n systemGeneratedVideoWidget.templateId,\n CuratedDashboardHelper.getDashboardTargetType(dashboard),\n activeAudiences?.map(a => a.masterId)\n ),\n systemGeneratedVideoWidget?.templateId\n )\n );\n\n // Non system generated dashboards are returned as per usual\n if (!isSystemGeneratedDashboard)\n return { widgets: ArrayHelper.sortBy(dashboard?.widgets, 'index') };\n\n // System generated dashboard have the video widget removed and returned as a separate video list\n return {\n widgets: dashboard?.widgets?.filter(widget => {\n if (widget.widgetId !== WidgetTypeId.ClassificationPinnedVideos)\n return true;\n\n if (widget.templateId === WidgetTemplate.ThumbnailVerticalList)\n return true;\n\n return false;\n }) ?? [],\n videoList: systemGeneratedVideoContent.data?.content ?? [],\n videoListWidgetId: systemGeneratedVideoWidget?.id\n };\n}\n","import React from 'react';\n\ntype TableOfContentsActiveOption = {\n setActiveId: (id: string) => void,\n headingElements: Element[],\n controlledId?: string,\n setControlledId?: (arg: string) => void\n};\n\n// a smooth scroll emits scroll events every frame; silence this long means it has finished.\n// Safari has no scrollend event, so completion is detected by settling instead\nconst SCROLL_SETTLE_MS = 150;\n// ignore sub-pixel scrollY jitter when deciding the user has scrolled back against the autoscroll\nconst SCROLL_REVERSAL_BUFFER_PX = 2;\n\nexport const useTableOfContentsActiveHeading = (\n { setActiveId, headingElements, controlledId, setControlledId }: TableOfContentsActiveOption\n) => {\n const scrollPositionRef = React.useRef(0);\n\n React.useEffect(() => {\n const callback = (headings: IntersectionObserverEntry[]) => {\n headings.forEach(heading => {\n if (controlledId) {\n setActiveId(controlledId);\n return;\n }\n if (heading.isIntersecting) {\n setActiveId(heading.target.id);\n scrollPositionRef.current = window.scrollY;\n } else {\n const scrollDistance = scrollPositionRef.current - window.scrollY;\n const isScrollingUp = scrollDistance > 0;\n const curIndex = headingElements.findIndex(h => h.id === heading.target.id);\n const prevHeading = headingElements[curIndex - 1];\n if (isScrollingUp && prevHeading?.id) {\n setActiveId(prevHeading?.id);\n }\n }\n });\n };\n\n const observer = new IntersectionObserver(callback, {\n // rootMargin top: same as the cv-nav-height\n rootMargin: '-67px 0px -80% 0px'\n });\n\n headingElements.forEach(element => observer.observe(element));\n\n return () => {\n observer.disconnect();\n };\n }, [ setActiveId, headingElements.length, controlledId ]);\n\n React.useEffect(() => {\n // controlledId tracks the heading post manual selection on the TOC.\n // Its absence means that the user is navigating through scrolling\n if (!controlledId || !setControlledId)\n return;\n\n let settleTimer: number;\n let hasSettled = false;\n let travelDirection = 0;\n let scrollTarget = window.scrollY;\n\n const restartSettleTimer = () => {\n window.clearTimeout(settleTimer);\n settleTimer = window.setTimeout(() => {\n hasSettled = true;\n }, SCROLL_SETTLE_MS);\n };\n\n const onScroll = () => {\n const delta = window.scrollY - scrollTarget;\n\n if (!travelDirection)\n travelDirection = Math.sign(delta); // sets initial travel direction\n\n // captures user taking over from autoscroll if the direction changes\n // might not be necessary given the distance travelled is quite short for reverse scrolling to happen\n const hasReversed = !!travelDirection\n && Math.sign(delta) === -travelDirection\n && Math.abs(delta) > SCROLL_REVERSAL_BUFFER_PX;\n\n if (hasSettled || hasReversed) {\n setControlledId('');\n return;\n }\n\n if (Math.sign(delta) === travelDirection)\n scrollTarget = window.scrollY;\n\n restartSettleTimer();\n };\n\n // when the target heading is already in position no scroll events fire at all,\n // so start the countdown immediately to let the next user scroll release the pin\n restartSettleTimer();\n window.addEventListener('scroll', onScroll, { passive: true });\n\n return () => {\n window.clearTimeout(settleTimer);\n window.removeEventListener('scroll', onScroll);\n };\n }, [ controlledId, setControlledId ]);\n};\n\n","import React from 'react';\n\nimport { usePrevious } from './usePrevious';\n\nconst HEADER_OFFSET = 80; // Size of header + some extra spacing\n\nexport const useTableOfContentsScroll = (elements: Element[], activeId: string) => {\n const [ hasDoneInitialScroll, setHasDoneInitialScroll ] = React.useState(false);\n\n const previousId = usePrevious(activeId);\n const currentId = activeId;\n\n React.useLayoutEffect(() => {\n if (!hasDoneInitialScroll || previousId !== currentId) {\n const target = elements.find(heading => heading && (heading?.id === currentId));\n\n if (target) {\n const rec = target.getBoundingClientRect();\n\n window.scrollBy({\n top: rec.top - HEADER_OFFSET,\n behavior: 'smooth'\n });\n \n if (!hasDoneInitialScroll)\n setHasDoneInitialScroll(true);\n }\n }\n }, [ elements, previousId, currentId, hasDoneInitialScroll ]);\n};\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, SignUpDescriptors, UserAction, WorkflowPhase } from 'libs/analytics/interfaces';\n\nimport { ActionButton } from 'libs/shared/components/actions/ActionButton';\nimport { AppLink } from 'libs/shared/components/app-link/AppLink';\nimport { EmptyState } from 'libs/shared/components/empty-states/EmptyState';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { BellFilledSvg } from 'libs/shared/images/svg/objects/BellFilledSvg';\nimport { BellSvg } from 'libs/shared/images/svg/objects/BellSvg';\nimport { Classification } from 'libs/shared/interfaces';\n\nconst namespace = 'subjects.classificationComingSoon';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface ComingSoonProps {\n data: Classification;\n onToggleFollow?: () => void;\n canFollowSubjects: boolean;\n imageUrl: string;\n showFollowButtonSpinner: boolean;\n showSignUp: boolean;\n signUpAppLink: Core.AppLink;\n}\n\nexport function ClassificationComingSoon(props: ComingSoonProps): JSX.Element {\n const isFollowing = !!props.data.followers?.data?.length;\n function onClick(): void {\n props.onToggleFollow?.();\n }\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <EmptyState className='pt-0'>\n <EmptyState.Image src={props.imageUrl} altText={getPhrase('comingSoon')} />\n\n <EmptyState.Heading>\n <Text phrase='comingSoon' />\n </EmptyState.Heading>\n\n <EmptyState.Info>\n <Text phrase={props.showSignUp ? 'infoAnon' : 'info'} />\n </EmptyState.Info>\n\n {props.canFollowSubjects && (\n <ActionButton\n svg={isFollowing ? BellFilledSvg : BellSvg}\n onClick={onClick}\n showSpinner={props.showFollowButtonSpinner}\n className={`btn follow-btn me-2 ${isFollowing ? 'btn-outline-dark' : 'btn-dark'}`}\n >\n <Text phrase={isFollowing ? 'following' : 'follow'} />\n </ActionButton>\n )}\n\n {props.showSignUp && !props.canFollowSubjects && (\n <AppLink\n appLink={props.signUpAppLink}\n className='btn btn-dark d-none d-lg-inline-block'\n analyticsOptions={{\n actionType: UserAction.Click,\n location: LocationContext.ClassificationComingSoon,\n entity: EntityType.AppLink,\n workflowPhase: WorkflowPhase.Start,\n descriptor: SignUpDescriptors.SignUp\n }}\n analyticsData={{}}\n tag='button'\n >\n {getPhrase('signUp')}\n </AppLink>\n )}\n </EmptyState>\n </LanguageNamespaceContext.Provider>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/core';\n\nimport { AudienceFilter } from 'libs/shared/apps/subjects/components/audience-filter/AudienceFilter';\nimport { PresentationAudience } from 'libs/shared/interfaces';\n\ninterface ClassificationDashboardAudiencesProps {\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n appLink: Core.AppLink;\n disabled: boolean;\n disablePersist: boolean;\n tooltip: string;\n}\n\nexport function ClassificationDashboardAudiences(props: ClassificationDashboardAudiencesProps): JSX.Element {\n return (\n <AudienceFilter\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n disabled={props.disabled}\n appLink={props.appLink}\n disablePersist={props.disablePersist}\n tooltip={props.tooltip}\n />\n );\n}\n","import React from 'react';\n\nimport { useViewModel } from 'libs/common/react/hooks/UseViewModel';\n\nimport { ClassificationTab } from '../components/classification-dashboard/classification-tabs/ClassificationTabs';\n\ninterface ViewModel {\n tab: ClassificationTab;\n on: boolean;\n}\n\nexport function useDirectoryTabProductTipSwitcher(initialTab?: ClassificationTab) {\n const initialState: ViewModel = {\n on: false,\n tab: initialTab || 'new-releases'\n };\n\n const [ viewModel, setViewModel ] = useViewModel<ViewModel>('directory:product:tip:switcher', initialState);\n\n React.useEffect(() => {\n if (!initialTab)\n return;\n\n setViewModel('tab', initialTab);\n }, [initialTab]);\n\n React.useEffect(() => {\n let interval: number = null;\n\n if (viewModel.on) {\n interval = window.setInterval(() => {\n if (viewModel.tab === 'new-releases' || viewModel.tab === 'all-topics')\n setViewModel('tab', viewModel.tab === 'new-releases' ? 'all-topics' : 'new-releases');\n else\n setViewModel('tab', viewModel.tab === 'curated-topic' ? 'video-list' : 'curated-topic');\n }, 2000);\n }\n\n return () => {\n window.clearInterval(interval);\n };\n }, [ viewModel.on, viewModel.tab ]);\n\n return {\n tab: viewModel.tab,\n isHighlighting: viewModel.on,\n start: () => setViewModel('on', true),\n stop: () => {\n setViewModel({\n on: false,\n tab: initialTab || viewModel.tab\n });\n }\n };\n}\n",":local {\n .curatedTopicTab {\n min-width: 6rem !important;\n }\n \n .tabTransition {\n transition: background-color .5s ease-in-out;\n }\n}","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { EntityType, LocationContext, UserAction } from 'libs/analytics/interfaces';\n\nimport { PillTab, PillTabSelector } from 'libs/shared/components/pill-tab-selector/PillTabSelector';\nimport { Breakpoints, useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { GridSvg } from 'libs/shared/images/svg/objects/GridSvg';\nimport { RectanglesSvg } from 'libs/shared/images/svg/objects/RectanglesSvg';\nimport { SparkleSvg } from 'libs/shared/images/svg/objects/SparkleSvg';\nimport { WidgetSeriesSvg } from 'libs/shared/images/svg/widgets/WidgetSeriesSvg';\nimport { Classification, Presentation } from 'libs/shared/interfaces';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { useDirectoryTabProductTipSwitcher } from '../../../hooks/useDirectoryTabProductTipSwitcher';\n\nimport styles from './classification-tabs.module.scss';\n\nconst namespace = 'shared.classificationDashboard';\n\nexport type ClassificationTab = 'new-releases' | 'all-topics' | 'curated-topic' | 'curriculum';\n\nfunction getTabs(\n props: ClassificationTabsProps,\n breakpoints: Breakpoints,\n activeTab: ClassificationTab,\n isHighlighting: boolean\n): PillTab[] {\n const showText = breakpoints.lg || breakpoints.xl || breakpoints.xxl || breakpoints.xs;\n\n function getTopicTabClassName(): string {\n let className = isHighlighting ? styles.tabTransition : '';\n\n if (breakpoints.xs)\n return className + ' w-100';\n\n if (showText)\n return className = ` ${styles.curatedTopicTab}`;\n\n return className;\n }\n\n if (TopicsHelper.isTopLevelTopic(props.classification)) {\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'newReleases') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'new-releases',\n svg: SparkleSvg,\n analyticsData: {\n id: 'new-releases',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'newReleases'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'allTopics') : '',\n appLink: props.appLinks?.classificationDirectory?.(props.classification),\n active: activeTab === 'all-topics',\n svg: GridSvg,\n analyticsData: {\n id: 'all-topics',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'allTopics'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationDirectory?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n }\n\n return [{\n name: showText ? LanguageService.getPhrase(namespace, 'topic') : '',\n appLink: props.appLinks?.classification?.(props.classification),\n active: activeTab === 'curated-topic',\n svg: RectanglesSvg,\n analyticsData: {\n id: 'curated-topic',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'topic'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classification?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: getTopicTabClassName()\n }, {\n name: showText ? LanguageService.getPhrase(namespace, 'curriculum') : '',\n appLink: props.appLinks?.classificationCurriculum?.(props.classification),\n active: activeTab === 'curriculum',\n svg: WidgetSeriesSvg,\n analyticsData: {\n id: 'curriculum',\n classificationId: props.classification.id,\n classificationName: props.classification.name,\n presentationId: props.presentation.id,\n presentationDescription: props.presentation.description,\n name: LanguageService.getPhrase(namespace, 'curriculum'),\n url: Core.AppLinkHelper.getHref(props.appLinks?.classificationCurriculum?.(props.classification))\n },\n analyticsOptions: {\n actionType: UserAction.Click,\n entity: EntityType.Url,\n location: LocationContext.MagicTabs\n },\n className: `${breakpoints.xs ? 'w-100' : ''} ${isHighlighting ? styles.tabTransition : ''}`\n }];\n}\n\ninterface ClassificationTabsProps {\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n classification: (classification: Classification | null) => Core.AppLink,\n classificationDirectory: (classification: Classification) => Core.AppLink,\n classificationCurriculum: (classification: Classification) => Core.AppLink\n };\n activeTab: ClassificationTab;\n}\n\nexport function ClassificationTabs(props: ClassificationTabsProps): JSX.Element {\n const breakpoints = useBreakpoints();\n const { tab, isHighlighting } = useDirectoryTabProductTipSwitcher(props.activeTab);\n\n return (\n <PillTabSelector\n borderRadius='sm'\n className={breakpoints.xs ? 'w-100' : ''}\n listClassName='d-flex flex-nowrap'\n tabs={getTabs(props, breakpoints, tab, isHighlighting)}\n />\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\n\nimport { Breadcrumb, Breadcrumbs } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { useBreakpoints } from 'libs/shared/hooks/useBreakpoints';\nimport { Classification, CuratedDashboard, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { AudienceHelper } from 'libs/shared/utils/audience-helper/AudienceHelper';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { ClassificationDashboardAudiences } from '../audiences/ClassificationDashboardAudiences';\nimport { ClassificationTab, ClassificationTabs } from '../classification-tabs/ClassificationTabs';\n\nfunction shouldHideAudiences(\n audiences: PresentationAudience[],\n activeAudiences: PresentationAudience[],\n activeTab: ClassificationTab,\n isEmpty: boolean,\n isComingSoon: boolean\n): boolean {\n if (isComingSoon)\n return true;\n\n if (isEmpty && !activeAudiences?.length)\n return true;\n\n if (!AudienceHelper.shouldShowAudiences(audiences))\n return true;\n\n if (activeTab === 'curriculum')\n return true;\n\n return false;\n}\n\ninterface ClassificationDashboardNavProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n appLinks: {\n audience: () => Core.AppLink,\n classification: (classification: Classification | null) => Core.AppLink,\n classificationDirectory: (classification: Classification) => Core.AppLink,\n classificationCurriculum: (classification: Classification) => Core.AppLink\n };\n activeTab: ClassificationTab;\n audiences: PresentationAudience[];\n activeAudiences: PresentationAudience[];\n getBreadcrumbs: () => Breadcrumb[];\n\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isComingSoon: boolean;\n isEmpty: boolean;\n isViewingCurrentPresentation: boolean;\n disableAudiences: boolean;\n audienceTooltip: string;\n\n // Forces audiences to be hidden regardless of shouldHideAudiences' own rules (e.g. channel topic dashboards)\n forceHideAudiences?: boolean;\n}\n\nexport function ClassificationDashboardNav(props: ClassificationDashboardNavProps): JSX.Element {\n const breakpoints = useBreakpoints();\n\n const hideAudiences = props.forceHideAudiences || shouldHideAudiences(\n props.audiences,\n props.activeAudiences,\n props.activeTab,\n props.isEmpty,\n props.isComingSoon\n );\n\n function canShowTabs(): boolean {\n if (!props.classification || !props.dashboard)\n return false;\n\n if (CuratedDashboardHelper.isSystemGeneratedDashboard(props.dashboard.widgets))\n return false;\n\n /**\n * For our top-level topics, we can show the topic tab if the topic has a directory dashboard.\n */\n if (TopicsHelper.isTopLevelTopic(props.classification))\n return props.hasTopicDirectoryDashboard;\n\n /**\n * For our curated topics, we can show the curriculum tab if the topic has one, which it should\n */\n if (props.classification.externalMetadata?.isCurated && props.hasTopicCurriculumDashboard)\n return true;\n\n return false;\n }\n\n function getContainerClass(): string {\n let className = 'd-flex flex-column py-3 mb-3';\n\n if (!props.isComingSoon)\n className += ' border-bottom';\n\n if ((canShowTabs() || hideAudiences) && !breakpoints.xs)\n return className;\n\n return className + ' row-gap-3';\n }\n\n function getTopRowClass(): string {\n if (hideAudiences) {\n if (breakpoints.xs)\n return 'd-flex flex-column justify-content-between row-gap-3';\n\n return 'd-flex align-items-center justify-content-between';\n }\n\n let className = '';\n\n className += 'd-flex align-items-center justify-content-between mb-1';\n\n if (breakpoints.xs)\n className += ' row-gap-3 mb-0';\n\n return className;\n }\n\n function getBottomRowClass(): string {\n let className = 'd-flex align-items-end justify-content-between';\n\n if (breakpoints.xs)\n className += ' row-gap-3 flex-wrap';\n\n return className;\n }\n\n return (\n <div className={getContainerClass()}>\n <div className={getTopRowClass()}>\n <Breadcrumbs breadcrumbs={props.getBreadcrumbs?.()} />\n\n {canShowTabs() && hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n\n <div className={getBottomRowClass()}>\n {!hideAudiences && (\n <ClassificationDashboardAudiences\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n appLink={props.appLinks.audience?.()}\n disabled={props.disableAudiences}\n tooltip={props.audienceTooltip}\n disablePersist={!props.isViewingCurrentPresentation}\n />\n )}\n\n {canShowTabs() && !hideAudiences && (\n <ClassificationTabs\n classification={props.classification}\n activeTab={props.activeTab}\n appLinks={props.appLinks}\n presentation={props.presentation}\n />\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsOptions, HashObject, LocationContext } from 'libs/analytics/interfaces';\n\nimport { ClassificationHeaderDetails } from 'libs/shared/apps/subjects/components/classification-dashboard/classification-header-details/ClassificationHeaderDetails';\nimport { CuratedClassificationEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/empty-state/CuratedClassificationEmptyState';\nimport { TableOfContentsContainer } from 'libs/shared/apps/subjects/components/classification-dashboard/table-of-contents/TableOfContents';\nimport { TeacherOnlyEmptyState } from 'libs/shared/apps/subjects/components/classification-dashboard/teacher-only/TeacherOnlyEmptyState';\nimport { useGetTopicsWidgets } from 'libs/shared/apps/subjects/hooks/useGetTopicsWidgets';\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { BannerHeader } from 'libs/shared/components/banner-header/BannerHeader';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { ExpandableTextInline } from 'libs/shared/components/expandable-text-inline/ExpandableTextInline';\nimport { DashboardFeedbackData } from 'libs/shared/components/feedback-form/FeedbackForm';\nimport { VideoList } from 'libs/shared/components/video-list/VideoList';\nimport { WidgetHeader } from 'libs/shared/components/widgets/curated-widgets/components/header/WidgetHeader';\nimport { InfiniteWidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/InfiniteWidgetContainerView';\nimport { WidgetContainerView } from 'libs/shared/components/widgets/curated-widgets/WidgetContainerView';\nimport { AllClassificationWidgetTemplates } from 'libs/shared/components/widgets/curated-widgets/WidgetProps';\nimport { ClassificationType } from 'libs/shared/enums/ClassificationType';\nimport { MediaQueryStrings } from 'libs/shared/enums/MediaQueries';\nimport { LocalPermissionName } from 'libs/shared/enums/PermissionName';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\nimport { useMediaQuery } from 'libs/shared/hooks/UseMediaQuery';\nimport { HasLocalPermissionsFunc, HasPermissionsFunc } from 'libs/shared/hooks/usePermissions';\nimport { useTableOfContentsActiveHeading } from 'libs/shared/hooks/useTableOfContentsActiveHeading';\nimport { useTableOfContentsScroll } from 'libs/shared/hooks/useTableOfContentsScroll';\nimport { CalendarEvent, CalendarEventContentType, Classification, CuratedDashboard, CuratedWidget, CuratedWidgetQueryParams, CurriculumData, DashboardStatus, DashboardTargetType, InteractiveMetadata, PartnerProfile, Presentation, PresentationAudience, Resource } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\nimport { WidgetHelper } from 'libs/shared/utils/WidgetHelper';\n\nimport { ClassificationComingSoon } from './classification-coming-soon/ClassificationComingSoon';\nimport { ClassificationDashboardNav } from './classification-dashboard-nav/ClassificationDashboardNav';\nimport { ClassificationTab } from './classification-tabs/ClassificationTabs';\n\nconst namespace = 'shared.classificationDashboard';\n\nfunction isHeadingWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.Blurb && widget.templateId === WidgetTemplate.Heading;\n}\n\nfunction isTopicWidget(widget: CuratedWidget) {\n return widget.widgetId === WidgetTypeId.CuratedClassifications || widget.widgetId === WidgetTypeId.Classifications;\n}\n\n// ClassificationAllVideos is the only widget type that supports infinite-scroll pagination so far\nconst InfiniteFetchWidgetIds: WidgetTypeId[] = [WidgetTypeId.ClassificationAllVideos];\n\nfunction shouldInfiniteFetch(widgets: CuratedWidget[], index: number): boolean {\n const currentWidget = widgets[index];\n\n if (!currentWidget) return false;\n\n return InfiniteFetchWidgetIds.includes(currentWidget.widgetId) && index === widgets.length - 1;\n}\n\n/**\n * Mirrors WidgetHelper's per-widget empty check (which InfiniteWidgetContainerView can't infer\n * on its own, since a completed fetch always returns one \"page\" object regardless of whether the\n * widget's own content is empty).\n */\nfunction isWidgetContentEmpty(widgets: CuratedWidget[]): boolean {\n const widget = widgets?.[0];\n\n if (!widget) return true;\n\n if (WidgetHelper.hasNoContent(widget.widgetId)) return false;\n\n if (!widget.content) return true;\n\n return Array.isArray(widget.content) && !widget.content.length;\n}\n\nexport interface ClassificationDashboardProps {\n dashboard: CuratedDashboard;\n classification: Classification;\n presentation: Presentation;\n hasPermissions: HasPermissionsFunc;\n hasLocalPermissions: HasLocalPermissionsFunc;\n resourceThumbnailFallbackImageUrl: string;\n hasTopicDirectoryDashboard: boolean;\n hasTopicCurriculumDashboard: boolean;\n isTertiaryCustomerWithoutExchange: boolean;\n tab: ClassificationTab;\n specialEvent?: CalendarEvent;\n curriculums: CurriculumData;\n channel?: PartnerProfile;\n\n audiences: PresentationAudience[];\n activeAudiences?: PresentationAudience[];\n\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate\n ) => Flight.Request;\n\n /**\n * Only needed by consumers that support cursor-paginated widgets (currently just\n * WidgetTypeId.ClassificationAllVideos). If omitted, that widget type falls back to fetching\n * its first page only via `getWidgetContentRequest`, with no \"load more\" pagination.\n */\n getWidgetContentRequestWithCursor?: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n cursor?: string\n ) => Flight.Request;\n\n getBannerActions?: () => ActionOptions[];\n getBreadcrumbs?: () => Breadcrumb[];\n onToggleFollow?: (classification: Classification, locationContext: LocationContext) => void;\n canFollowSubjects: boolean;\n onSubmitFeedback?: (feedback: DashboardFeedbackData) => Promise<void>;\n onDownloadAllClick?: (resources: Resource[], fileName: string, analyticsData?: HashObject) => void;\n\n appLinks?: AllClassificationWidgetTemplates['appLinks'] & {\n signUp: () => Core.AppLink,\n widgetWizard: () => Core.AppLink,\n previewQuestions: (interactive: InteractiveMetadata) => Core.AppLink,\n classificationCurriculum: (classification: Classification) => Core.AppLink,\n audience: () => Core.AppLink\n };\n\n imageCdnUrl: string;\n imageUrls?: AllClassificationWidgetTemplates['imageUrls'];\n emptyImageUrl: string;\n comingSoonImageUrl?: string;\n\n analyticsOptions?: AnalyticsOptions;\n analyticsData?: HashObject;\n\n scrollToWidgetId?: string;\n tableOfContentsId?: string;\n\n // Means the dashboard contains no linked or working filters\n isReadonly?: boolean;\n\n // Means the dashboard is being previewed by ClickView staff either in product or in curator\n isPreviewing?: boolean;\n\n // Means the parent topic for the dashboard has a status of \"Coming Soon\"\n isComingSoon?: boolean;\n\n showFollowButtonSpinner?: boolean;\n \n isViewCurrentPresentation?: boolean;\n\n // By default widgets will always be lazyloaded. We override this behaviour only in extenuating \n // circumstances, such as dynamic rendering for SEO.\n lazyLoad?: boolean;\n\n moviesAndTv?: boolean;\n\n isTeacherOnly?: boolean;\n \n contentType?: CalendarEventContentType;\n\n isBot?: boolean;\n\n settings?: AllClassificationWidgetTemplates['settings'];\n\n commonVideoProps: CommonVideoProps;\n}\n\nClassificationDashboard.defaultProps = {\n appLinks: {}\n};\n\nexport function ClassificationDashboard(props: ClassificationDashboardProps): JSX.Element {\n const { widgets, videoList, videoListWidgetId } = useGetTopicsWidgets(props.dashboard, props.activeAudiences);\n\n const isSmallScreen = useMediaQuery(MediaQueryStrings.LGDown);\n const headingRef = React.useRef<Set<Element>>(new Set());\n\n const initialEmptyWidgets = React.useMemo(() => {\n return widgets.reduce((acc: HashObject<boolean>, widget) => {\n acc[widget.id] = false;\n return acc;\n }, {});\n }, [widgets?.length]);\n\n const [ emptyWidgets, setEmptyWidgets ] = React.useState(initialEmptyWidgets);\n\n const [ controlledId, setControlledId ] = React.useState(props.tableOfContentsId);\n\n const [ tableOfContentActiveId, setTableOfContentActiveId ] = React.useState<string>('');\n\n const headingElements = Array.from(headingRef.current);\n useTableOfContentsScroll(headingElements, controlledId);\n useTableOfContentsActiveHeading({\n setActiveId: setTableOfContentActiveId,\n headingElements,\n controlledId,\n setControlledId\n });\n\n const isHubDashboard = props.classification.type === ClassificationType.Hub;\n const isChannelTopic = !!props.dashboard?.metadata?.channelId;\n\n function shouldShowEmptyState(): boolean {\n if (props.isComingSoon)\n return false;\n\n if (props.isTeacherOnly)\n return false;\n\n if (!props.dashboard)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Archived && !props.isReadonly)\n return true;\n\n if (props.dashboard.status === DashboardStatus.Draft && !props.isPreviewing)\n return true;\n\n if (!widgets?.length)\n return true;\n\n if (videoList && videoList.length)\n return false;\n\n return Object.values(emptyWidgets).every(state => !!state);\n }\n\n function getWidgetContentRequest(\n id: string,\n widgetTypeId: WidgetTypeId,\n template: WidgetTemplate,\n cursor?: string\n ): Flight.Request {\n const params = CuratedDashboardHelper.getWidgetParams(\n widgetTypeId,\n template,\n CuratedDashboardHelper.getDashboardTargetType(props.dashboard),\n props.activeAudiences?.map(a => a.masterId),\n props.curriculums.preferredCurriculum?.id\n );\n\n if (cursor && props.getWidgetContentRequestWithCursor)\n return props.getWidgetContentRequestWithCursor(id, params, template, cursor);\n\n return props.getWidgetContentRequest(id, params, template);\n }\n\n const showEmptyState = shouldShowEmptyState();\n\n React.useEffect(() => {\n /**\n * When we add the first widget of the dashboard, the showEmptyState is `true`, the WidgetContainer is not going to be rendered to lazyload the `content`\n * so we set the emptyWidget to initial make sure the widget container is rendered to lazyload `widget.content`\n * and let the WidgetContainer to re-set the empty state based on the actual `widget.content` from backend\n */\n if (showEmptyState) {\n setEmptyWidgets(initialEmptyWidgets);\n }\n }, [widgets?.length]);\n\n const onSetIsEmpty = React.useCallback((widgetId: string, isEmpty: boolean) => {\n if (emptyWidgets[widgetId] === isEmpty)\n return;\n\n const newEmptyState = {\n ...emptyWidgets,\n [widgetId]: isEmpty\n };\n\n // The logic beneath this if-block doesn't apply to classification directories. This is because\n // classification directories don't support audience filtering, so widgets should never be empty,\n // meaning headings should never be hidden.\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.ClassificationDirectory)) {\n setEmptyWidgets(newEmptyState);\n return;\n }\n\n let index = 0;\n\n /**\n * Every time a widget is identified as empty, we check each heading blurb widget\n * to see if it should be hidden. This will be the case when all widgets beneath a heading\n * (up until the next heading) are empty.\n */\n while (index < widgets.length) {\n const currentWidget = widgets[index];\n\n if (!isHeadingWidget(currentWidget)) {\n index++;\n continue;\n }\n\n let isHeadingEmpty = true;\n let subWidgetIndex = index + 1;\n\n while (isHeadingEmpty && subWidgetIndex < widgets.length) {\n const headingSubWidget = widgets[subWidgetIndex];\n\n if (isHeadingWidget(headingSubWidget))\n break;\n\n if (!newEmptyState[headingSubWidget.id] && !isTopicWidget(headingSubWidget))\n isHeadingEmpty = false;\n\n subWidgetIndex++;\n }\n\n index = subWidgetIndex;\n\n newEmptyState[currentWidget.id] = isHeadingEmpty;\n }\n\n setEmptyWidgets(newEmptyState);\n }, [ emptyWidgets, widgets ]);\n\n function hideWidget(widget: CuratedWidget): boolean {\n return isHeadingWidget(widget) && emptyWidgets[widget.id];\n }\n\n function useLargeDashboardSpacing(): boolean {\n const target = CuratedDashboardHelper.getDashboardTargetType(props.dashboard);\n\n if (props.moviesAndTv || target === DashboardTargetType.ClassificationCurriculum)\n return false;\n\n return true;\n }\n\n function getWidgetHeading(widget: CuratedWidget, index: number): string {\n if (widget.widgetId === WidgetTypeId.ClassificationDashboardExternalMedia) {\n const previousWidget = widgets[index - 1];\n\n if (emptyWidgets[previousWidget.id])\n return widget.name.replace('Other videos', 'Videos');\n\n return widget.name;\n }\n\n return widget.name;\n }\n\n const widgetsInTableOfContents = widgets.filter(w => {\n return !hideWidget(w) && !!w.metadata?.showInTableOfContents;\n });\n\n const isTopicOnlyDashboard = widgets.every(isTopicWidget);\n\n const shouldShowTableOfContents = widgetsInTableOfContents.length >= 2;\n const shouldShowSideTableOfContents = shouldShowTableOfContents && !isSmallScreen;\n\n const shouldShowTopicCounts = (\n props.settings?.hasTopicDirectories &&\n TopicsHelper.isTopLevelTopic(props.classification) &&\n !props.isTertiaryCustomerWithoutExchange &&\n !isHubDashboard\n );\n\n /**\n * We don't put the .topic-dashboard class when we're in a movies and tv classification\n * because we don't want the extra padding between widgets.\n */\n return (\n <div className={`bg-white px-4 ${useLargeDashboardSpacing() ? 'dashboard-spacing-lg' : ''}`}>\n\n <BannerHeader\n type={isChannelTopic ? 'channel-topic' : 'default'}\n logo={isChannelTopic && props.channel?._logo.value}\n logoBgColour={isChannelTopic && props.channel?._colour.value}\n heading={props.classification.name}\n banner={props.classification.banner}\n imageCdnUrl={props.imageCdnUrl}\n actions={props.getBannerActions?.()}\n actionsDropdownClassName='btn btn-outline-dark'\n specialEvent={props.specialEvent}\n calendarTheme={{\n background: 'bg-light-blue',\n border: 'border-light-blue'\n }}\n showComingSoon={props.isComingSoon}\n detailsComponent={shouldShowTopicCounts ?\n () => <ClassificationHeaderDetails classification={props.classification} /> :\n null\n }\n />\n\n {!isHubDashboard ? (\n <ClassificationDashboardNav\n forceHideAudiences={isChannelTopic}\n dashboard={props.dashboard}\n classification={props.classification}\n presentation={props.presentation}\n appLinks={props.appLinks}\n activeTab={props.tab}\n audiences={props.audiences}\n activeAudiences={props.activeAudiences}\n getBreadcrumbs={props.getBreadcrumbs}\n hasTopicDirectoryDashboard={props.hasTopicDirectoryDashboard}\n hasTopicCurriculumDashboard={props.hasTopicCurriculumDashboard}\n isComingSoon={props.isComingSoon}\n isEmpty={showEmptyState}\n isViewingCurrentPresentation={props.isViewCurrentPresentation}\n disableAudiences={isTopicOnlyDashboard || props.isReadonly}\n audienceTooltip={isTopicOnlyDashboard ? LanguageService.getPhrase(namespace, 'audienceTooltip') : ''}\n />\n ) : (\n <div className='py-3 mb-3 border-bottom'>\n <div className='mt-3'>\n <ExpandableTextInline>\n {() => (\n <p className='mb-0'>{props.classification.description}</p>\n )}\n </ExpandableTextInline>\n </div>\n </div>\n )}\n\n {props.isComingSoon && (\n <ClassificationComingSoon\n imageUrl={props.comingSoonImageUrl}\n data={props.classification}\n canFollowSubjects={props.canFollowSubjects}\n showFollowButtonSpinner={props.showFollowButtonSpinner}\n onToggleFollow={() => props.onToggleFollow(props.classification, LocationContext.ClassificationComingSoon)}\n showSignUp={!props.hasLocalPermissions(LocalPermissionName.FollowComingSoonTopics)}\n signUpAppLink={props.appLinks.signUp?.()}\n />\n )}\n\n {!props.isComingSoon && (\n <div className={`${shouldShowSideTableOfContents ? 'row no-wrap' : ''}`}>\n {shouldShowTableOfContents && (\n <TableOfContentsContainer\n widgets={widgetsInTableOfContents}\n title={props.classification.name}\n activeId={tableOfContentActiveId}\n clickable={!props.isReadonly}\n analyticsData={props.analyticsData}\n setControlledId={setControlledId}\n isSmallScreen={isSmallScreen}\n />\n )}\n\n <div className={shouldShowSideTableOfContents ? 'col-9 order-0' : ''}>\n {widgets.map((widget, idx) => {\n if (hideWidget(widget))\n return <React.Fragment key={widget.id}></React.Fragment>;\n\n if (InfiniteFetchWidgetIds.includes(widget.widgetId)) {\n return (\n <InfiniteWidgetContainerView<CuratedWidget, CuratedWidget, AllClassificationWidgetTemplates>\n index={idx}\n key={widget.id}\n item={widget}\n infiniteFetch={shouldInfiniteFetch(widgets, idx) && !!props.getWidgetContentRequestWithCursor}\n dashboardTarget={CuratedDashboardHelper.getDashboardTargetType(props.dashboard)}\n\n getName={w => getWidgetHeading(w, idx)}\n getWidgetMetadata={w => w.metadata}\n getContent={w => w.content}\n getCursor={w => w.cursor}\n getRequest={cursor => (\n getWidgetContentRequest(widget.id, widget.widgetId, widget.templateId, cursor)\n )}\n isEmptyPredicate={isWidgetContentEmpty}\n\n audiences={props.audiences}\n appLinks={props.appLinks}\n commonVideoProps={props.commonVideoProps}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n resultsTransformers={WidgetHelper.getWidgetResultsTransformers()}\n\n presentation={props.presentation}\n analyticsData={props.analyticsData}\n imageCdnUrl={props.imageCdnUrl}\n imageUrls={props.imageUrls}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n lazyLoad={props.lazyLoad}\n\n headingElementRef={headingRef}\n hasTableOfContents={shouldShowSideTableOfContents}\n isScrollToTargetWidget={props.scrollToWidgetId === widget.id}\n isBot={props.isBot}\n isPreviewing={props.isReadonly}\n isEditing={props.isReadonly}\n curriculums={props.curriculums}\n contentType={props.contentType}\n\n setIsEmpty={isEmpty => onSetIsEmpty(widget.id, isEmpty)}\n\n getSelectedItems={null}\n appLinkOptions={null}\n />\n );\n }\n\n return (\n <WidgetContainerView\n widgetCollection={DashboardTargetType.Classification}\n headingElementRef={headingRef}\n key={widget.id}\n id={widget.id}\n name={getWidgetHeading(widget, idx)}\n description={widget.description}\n classification={props.classification}\n templateId={widget.templateId}\n widgetTypeId={widget.widgetId}\n audiences={props.audiences}\n getContentRequest={getWidgetContentRequest}\n setIsEmpty={onSetIsEmpty}\n appLinks={props.appLinks}\n presentation={props.presentation}\n analyticsData={props.analyticsData}\n isScrollToTargetWidget={props.scrollToWidgetId === widget.id}\n imageCdnUrl={props.imageCdnUrl}\n imageUrls={props.imageUrls}\n onSubmitFeedback={props.onSubmitFeedback}\n onDownloadAllClick={props.onDownloadAllClick}\n metadata={widget.metadata}\n isBot={props.isBot}\n hasTableOfContents={shouldShowSideTableOfContents}\n lazyLoad={props.lazyLoad}\n dashboardTarget={CuratedDashboardHelper.getDashboardTargetType(props.dashboard)}\n widgetIndex={idx}\n hasPermissions={props.hasPermissions}\n hasLocalPermissions={props.hasLocalPermissions}\n isPreviewing={props.isReadonly}\n contentType={props.contentType}\n resourceThumbnailFallbackImageUrl={props.resourceThumbnailFallbackImageUrl}\n onToggleFollowClassification={props.onToggleFollow}\n settings={props.settings}\n isEditing={props.isReadonly}\n isTertiaryCustomerWithoutExchange={props.isTertiaryCustomerWithoutExchange}\n commonVideoProps={props.commonVideoProps}\n curriculums={props.curriculums}\n\n // TODO: Do we actually need this shit if it wasn't even being passed in?\n limitTotalItems={false}\n seeMoreLink={null}\n onClickRemoveItem={null}\n badgeComponent={null}\n />\n );\n })}\n </div>\n\n {!!videoList?.length && (\n <>\n <WidgetHeader name={LanguageService.getPhrase(namespace, 'videos')} />\n <VideoList\n videos={videoList}\n getVideoAppLink={(video, opts) => props.appLinks.videoType(\n video,\n { ...opts, contextId: videoListWidgetId, includeContext: opts.includeContext }\n )}\n hasPermissions={props.hasPermissions}\n presentationAudiences={props.audiences}\n getPreviewQuestionsAppLink={props.appLinks.previewQuestions}\n commonVideoProps={props.commonVideoProps}\n />\n </>\n )}\n </div>\n )}\n\n {showEmptyState && (\n <CuratedClassificationEmptyState\n dashboard={props.dashboard}\n isReadonly={props.isReadonly}\n imageUrl={props.emptyImageUrl}\n addWidgetApplink={props.appLinks.widgetWizard}\n />\n )}\n\n {props.isTeacherOnly && (\n <TeacherOnlyEmptyState\n imageUrl={props.emptyImageUrl}\n ctaAppLink={() => props.appLinks.allTopics(props.classification.presentationId)}\n />\n )}\n </div>\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\n\nimport { ContentPartnerDashboard } from 'libs/shared/apps/content-partners/components/content-partner-dashboard/ContentPartnerDashboard';\nimport { DiscoverDashboard } from 'libs/shared/apps/discover/components/discover-dashboard/DiscoverDashboard';\nimport { CompanyDashboard } from 'libs/shared/apps/movies-and-tv/components/company-dashboard/CompanyDashboard';\nimport { MoviesAndTvDashboard } from 'libs/shared/apps/movies-and-tv/components/movies-and-tv-dashboard/MoviesAndTvDashboard';\nimport { StreamableCompanyDashboard } from 'libs/shared/apps/streamable-learning/components/company-dashboard/StreamableCompanyDashboard';\nimport { StreamableDiscoverDashboard } from 'libs/shared/apps/streamable-learning/components/dashboard/StreamableDiscoverDashboard';\nimport { ClassificationDashboard } from 'libs/shared/apps/subjects/components/classification-dashboard/ClassificationDashboard';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { BannerPortalContextProvider } from 'libs/shared/context/BannerPortalContext';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { WidgetTemplate } from 'libs/shared/enums/WidgetTemplate';\nimport { CalendarEventContentType, Classification, Company, CuratedDashboard, CuratedWidgetData, CuratedWidgetQueryParams, DashboardStatus, DashboardTargetType, PartnerProfile, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CommonVideoProps } from 'libs/shared/interfaces/CommonVideoProps';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { DialogHelper } from 'libs/shared/utils/DialogHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { DashboardWidgetImageUrls } from 'shared/constants/DashboardWidgetImageUrls';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\nimport { MockHasPermissions } from 'shared/utils/MockHasPermissions';\n\nimport { useMockCurriculums } from 'apps/curriculums/hooks/useMockCurriculums';\nimport { CURATOR_HARD_CODED_SETTINGS } from 'apps/dashboard-editor/constants/CuratorHardCodedSettings';\nimport { DashboardEditorHelper } from 'apps/dashboard-editor/utils/DashboardEditorHelper';\n\nconst BANNER_CONTAINER_CLASS_NAME = 'banner-portal-container';\n\ninterface DashboardEditorPreviewProps {\n dashboard: CuratedDashboard<CuratedWidgetData>;\n presentation?: Presentation;\n cvLivePresentation?: Presentation;\n availablePresentations?: Presentation[];\n classification?: Classification;\n getWidgetContentRequest: (\n id: string,\n params: CuratedWidgetQueryParams,\n widgetTemplate: WidgetTemplate,\n presentation?: Presentation,\n cursor?: string\n ) => Flight.Request;\n getBreadcrumbs?: () => Breadcrumb[];\n audiences?: PresentationAudience[];\n emptyImageUrl?: string;\n scrollToWidgetId?: string;\n moviesAndTvIconUrl?: string;\n company?: Company;\n commonVideoProps: CommonVideoProps;\n partnerProfile?: PartnerProfile;\n onClickSearchAllVideos?: () => void;\n}\n\nexport function DashboardEditorPreview(props: DashboardEditorPreviewProps): JSX.Element {\n const curriculums = useMockCurriculums();\n\n React.useEffect(() => {\n if (DashboardHelper.canEdit(props.dashboard))\n return;\n\n const isPublished = props.dashboard.status === DashboardStatus.Published;\n\n const message = isPublished ?\n 'Published dashboards can\\'t be edited.' :\n 'Archived dashboards can\\'t be edited.';\n\n DialogHelper.render(\n <div>\n <p>{message}</p>\n\n {isPublished && (\n <p>If you would like to make some changes, please create a copy of this dashboard.</p>\n )}\n </div>,\n {\n title: 'This dashboard can\\'t be edited',\n submitButtonProps: {\n text: 'Okay',\n variant: 'dark'\n }\n }\n );\n }, []);\n\n function mockOnSubmitFeedback(): Promise<void> {\n return new Promise(resolve => {\n window.setTimeout(() => {\n resolve();\n }, 300);\n });\n }\n\n const isStreamableProduct = DashboardHelper.isProduct(\n props.dashboard,\n ProductId.StreamableLearning,\n props.cvLivePresentation?.id\n );\n\n if (CuratedDashboardHelper.isClassificationDashboard(\n CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard)\n )) {\n const targetType = CuratedDashboardHelper.getDashboardTargetType(props.dashboard);\n\n return (\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <div className={BANNER_CONTAINER_CLASS_NAME} />\n <div className='container px-4'>\n <ClassificationDashboard\n getWidgetContentRequest={props.getWidgetContentRequest}\n dashboard={props.dashboard}\n classification={props.classification}\n getBreadcrumbs={props.getBreadcrumbs}\n audiences={props.audiences}\n presentation={props.presentation}\n imageCdnUrl={ClickView.Config.Urls.ImageAPI}\n resourceThumbnailFallbackImageUrl={null}\n emptyImageUrl={props.emptyImageUrl}\n imageUrls={DashboardWidgetImageUrls}\n appLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n onSubmitFeedback={mockOnSubmitFeedback}\n isBot={false}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isPreviewing\n isReadonly\n canFollowSubjects\n scrollToWidgetId={props.scrollToWidgetId}\n settings={CURATOR_HARD_CODED_SETTINGS}\n contentType={props.classification?.presentationId === props.cvLivePresentation?.id &&\n CalendarEventContentType.Livestream\n }\n onDownloadAllClick={() => {}}\n hasTopicDirectoryDashboard\n tab={TopicsHelper.getActiveTopicTab(props.classification, targetType)}\n hasTopicCurriculumDashboard={true}\n isTertiaryCustomerWithoutExchange={false}\n commonVideoProps={props.commonVideoProps}\n curriculums={curriculums}\n />\n </div>\n </BannerPortalContextProvider>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.Discover)) {\n if (isStreamableProduct) {\n return (\n <div className='container px-4'>\n <StreamableDiscoverDashboard\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n audiences={props.audiences}\n isReadonly\n commonVideoProps={props.commonVideoProps}\n />\n </div>\n );\n }\n\n return (\n <div className='container px-4'>\n <DiscoverDashboard\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n audiences={props.audiences}\n onSubmitFeedback={mockOnSubmitFeedback}\n removeFromVideoHistory={Promise.resolve}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n settings={CURATOR_HARD_CODED_SETTINGS}\n isReadonly\n commonVideoProps={props.commonVideoProps}\n\n // always show calendar header for preview in curation studio\n showCalendar\n availablePresentations={props.availablePresentations}\n isTertiaryCustomerWithoutExchange={false}\n />\n </div>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.MoviesAndTv)) {\n return (\n <div className='container px-4'>\n <MoviesAndTvDashboard\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isReadonly\n showPreviewingTooltip\n moviesAndTvIconUrl={props.moviesAndTvIconUrl}\n products={{\n hasProduct: () => true,\n isLoadingProducts: false,\n products: null\n }}\n commonVideoProps={props.commonVideoProps}\n settings={CURATOR_HARD_CODED_SETTINGS}\n />\n </div>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.Company)) {\n if (isStreamableProduct) {\n return (\n <div className='container px-4'>\n <StreamableCompanyDashboard\n dashboard={props.dashboard}\n company={props.company}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n presentation={props.presentation}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isReadOnly\n getBreadcrumbs={props.getBreadcrumbs}\n commonVideoProps={props.commonVideoProps}\n />\n </div>\n );\n }\n return (\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <div className={BANNER_CONTAINER_CLASS_NAME} />\n <div className='container px-4'>\n <CompanyDashboard\n dashboard={props.dashboard}\n company={props.company}\n getWidgetContentRequest={props.getWidgetContentRequest}\n emptyImageUrl={props.emptyImageUrl}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n isReadonly\n getBreadcrumbs={props.getBreadcrumbs}\n commonVideoProps={props.commonVideoProps}\n />\n </div>\n </BannerPortalContextProvider>\n );\n }\n\n if (CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.PartnerProfile)) {\n return (\n <BannerPortalContextProvider containerClassName={BANNER_CONTAINER_CLASS_NAME}>\n <div className={BANNER_CONTAINER_CLASS_NAME} />\n <div className='container px-4'>\n <ContentPartnerDashboard\n partnerProfile={props.partnerProfile}\n isInContentRegion\n isAuthenticated\n onClickSignUp={null}\n dashboard={props.dashboard}\n getWidgetContentRequest={props.getWidgetContentRequest}\n breadcrumbs={props.getBreadcrumbs?.()}\n emptyImageUrl={props.emptyImageUrl}\n widgetAppLinks={DashboardEditorHelper.getWidgetAppLinks(props.dashboard.id)}\n scrollToWidgetId={props.scrollToWidgetId}\n hasPermissions={MockHasPermissions}\n hasLocalPermissions={() => true}\n commonVideoProps={props.commonVideoProps}\n isPreviewing\n settings={CURATOR_HARD_CODED_SETTINGS}\n onClickSearchAllVideos={props.onClickSearchAllVideos}\n />\n </div>\n </BannerPortalContextProvider>\n );\n }\n return <></>;\n}\n",":local {\n .badge {\n gap: map-get($spacers, 1);\n padding-right: 1rem;\n\n &.draftLight {\n color: $gray-800;\n border: 0.0625rem solid $gray-800;\n background-color: rgba($gray-800, 0.05);\n }\n\n &.draftDark {\n color: $gray-300;\n border: 0.0625rem solid $gray-300;\n background-color: rgba($gray-300, 0.05);\n }\n\n &.published {\n color: $success;\n border: 0.0625rem solid $success;\n background-color: rgba($success, 0.05);\n }\n\n &.archived {\n color: $danger;\n border: 0.0625rem solid $danger;\n background-color: rgba($danger, 0.05);\n }\n }\n}","import React from 'react';\n\nimport { DashboardStatusConfig } from 'libs/shared/apps/subjects/constants/DashboardStatusConfig';\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { DashboardStatus } from 'libs/shared/interfaces';\n\nimport styles from './dashboard-status-badge.module.scss';\n\nfunction getClassName(props: DashboardStatusBadgeProps): string {\n let className = `rounded-pill d-flex align-items-center ps-2 py-1 fw-semibold ms-2 ${styles.badge}`;\n\n switch (props.status) {\n case DashboardStatus.Published:\n className += ` ${styles.published}`;\n break;\n case DashboardStatus.Archived:\n className += ` ${styles.archived}`;\n break;\n case DashboardStatus.Draft:\n className += ` ${props.darkMode ? styles.draftDark : styles.draftLight}`;\n break;\n }\n\n if (props.wrapperClassName)\n className += ` ${props.wrapperClassName}`;\n\n return className;\n}\n\ninterface DashboardStatusBadgeProps {\n status: DashboardStatus;\n darkMode?: boolean;\n wrapperClassName?: string;\n}\n\nexport function DashboardStatusBadge(props: DashboardStatusBadgeProps): JSX.Element {\n const { statusName, svg } = DashboardStatusConfig[props.status];\n\n return (\n <div className={getClassName(props)}>\n <SvgContainer svg={svg} />\n <div>{statusName}</div>\n </div>\n );\n}\n",":local {\n .sticky {\n position: sticky;\n top: 0;\n z-index: 3;\n }\n}","import React from 'react';\n\nimport { DashboardStatusBadge } from 'libs/shared/apps/subjects/components/classification-dashboard/dashboard-status-badge/DashboardStatusBadge';\nimport { ActionOptions, Actions } from 'libs/shared/components/actions/Actions';\nimport { CuratedDashboard, Presentation } from 'libs/shared/interfaces';\n\nimport styles from './dashboard-sticky-header.module.scss';\n\ninterface DashboardStickyHeaderProps {\n presentation?: Presentation;\n dashboard: CuratedDashboard;\n isSaving: boolean;\n getActions: () => ActionOptions[];\n}\n\nexport function DashboardStickyHeader(props: DashboardStickyHeaderProps): JSX.Element {\n return (\n <div className={`bg-white border-bottom ${styles.sticky}`}>\n <div className='d-flex justify-content-between align-items-center'>\n <div className='d-flex align-items-center'>\n <DashboardStatusBadge status={props.dashboard?.status} />\n\n <div className='d-flex flex-column ms-2'>\n <h2 className='font-size-normal mb-0'>\n {props.presentation?.description ? `[${props.presentation?.description}]` : ''} {props.dashboard?.name}\n </h2>\n <small className='text-secondary'>\n {props.isSaving ? 'Saving...' : 'Saved'}\n </small>\n </div>\n </div>\n\n <div className='p-2'>\n <Actions className='justify-content-end' actions={props.getActions()} />\n </div>\n </div>\n </div>\n );\n}\n",":local {\n $top-nav-height: 3rem;\n $loader-size: 5rem;\n\n .container {\n position: absolute;\n top: $top-nav-height;\n height: 100%;\n width: 100%;\n z-index: 100;\n background-color: rgba(255, 255, 255, 0.8);\n }\n\n .content {\n width: $loader-size;\n height: $loader-size;\n }\n}","import React from 'react';\n\nimport styles from './loading-mask.module.scss';\n\nexport function LoadingMask(): JSX.Element {\n return (\n <div className={`d-flex justify-content-center align-items-center ${styles.container}`}>\n <div className={`${styles.content} spinner-border`} role='status'>\n <span className='visually-hidden'>Loading...</span>\n </div>\n </div>\n );\n}\n",":local {\n $gap: 2.063rem;\n\n .indicator {\n border-top: 0.125rem solid $blue;\n left: 0;\n position: absolute;\n }\n\n .above {\n top: -$gap;\n }\n\n .below {\n bottom: -$gap;\n }\n}","import React from 'react';\n\nimport styles from './drop-indicator.module.scss';\n\ninterface DropIndicatorProps {\n dragDirection: 'up' | 'down';\n}\n\nexport function DropIndicator(props: DropIndicatorProps) {\n if (!props.dragDirection) {\n return null;\n }\n\n const position = props.dragDirection === 'up' ? styles.above : styles.below;\n\n return <hr className={`${styles.indicator} ${position} visible w-100 position-absolute`} />;\n}\n","import React from 'react';\n\nimport { SvgContainer } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTypeId } from 'libs/shared/enums/WidgetTypeId';\n\nimport { CuratorWidgetTypeIdConfig } from 'apps/dashboard-editor/constants/CuratorWidgetTypeIdConfig';\n\ninterface WidgetIconProps {\n id: WidgetTypeId;\n}\n\nexport function DashboardWidgetIcon(props: WidgetIconProps) {\n const config = CuratorWidgetTypeIdConfig[props.id];\n \n if (!config)\n return <></>;\n\n return (\n <div className={`text-white rounded ${config.bgColourClass}`}>\n <SvgContainer svg={config.icon} />\n </div>\n );\n}\n",":local {\n $item-height: 14rem;\n $number-container-size: 1rem;\n $svg-container-height: 3.5rem;\n\n .widgetNumber {\n display: block;\n }\n\n .widgetHandle {\n display: none;\n }\n\n .widgetActions {\n visibility: hidden;\n }\n\n .widgetItem {\n height: $item-height;\n \n &:hover {\n background-color: $light-blue;\n\n .widgetNumber {\n display: none;\n }\n\n .widgetHandle {\n display: block;\n }\n\n .widgetActions {\n visibility: visible;\n }\n }\n\n &.disabled {\n background-color: $gray-200;\n &:hover {\n .widgetNumber {\n display: block;\n }\n \n .widgetHandle {\n display: none;\n }\n }\n }\n }\n\n .numberContainer {\n flex-shrink: 0;\n width: $number-container-size;\n height: $number-container-size;\n }\n\n .svgContainer {\n height: $svg-container-height;\n color: $gray-400;\n }\n\n .disabledAction {\n pointer-events: all !important; // overrides bootstrap 'disabled' class\n }\n}","import React from 'react';\n\nimport { HashObject } from 'libs/common/react/interfaces';\n\nimport { ActionsDropdown, DropdownActionOptions } from 'libs/shared/components/actions/ActionsDropdown';\nimport { PropsWithSortableItemProps } from 'libs/shared/components/sortable/SortableItemWrapper';\nimport { SvgContainer, SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { DropIndicator } from 'shared/components/drop-indicator/DropIndicator';\nimport { Actions, AppChannels } from 'shared/constants';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { DashboardWidgetIcon } from 'apps/dashboard-editor/components/dashboard-widget-icon/DashboardWidgetIcon';\n\nimport styles from './widget-editor-item.module.scss';\n\ninterface WidgetEditorItemProps extends Partial<PropsWithSortableItemProps<CuratedWidget>> {\n index: number;\n templates: CuratedWidgetTemplate[];\n dragHandleIcon: SvgIcon;\n dragHandleIconSize: SvgContainerSize;\n dashboard: CuratedDashboard;\n style?: HashObject;\n setScrollToWidgetId?: (id: string) => void;\n headingClassName?: string;\n isReadOnlyWidget?: boolean;\n}\n\nexport const WidgetEditorItem = React.forwardRef(\n (props: WidgetEditorItemProps, ref: React.LegacyRef<HTMLDivElement>) => {\n const isDisabled = !DashboardHelper.canEdit(props.dashboard) || props.isReadOnlyWidget;\n\n const preventHighlight = React.useRef(false);\n\n const toggleId = `dropdown-toggle-${props.index}`;\n\n function handleClick(e: React.MouseEvent<HTMLElement>): void {\n if (e.currentTarget.id === toggleId) {\n preventHighlight.current = true;\n return;\n }\n\n if (preventHighlight.current) {\n preventHighlight.current = false;\n return;\n }\n\n props.setScrollToWidgetId?.(props.id);\n }\n\n function getActions(): DropdownActionOptions[] {\n if (!DashboardHelper.canEdit(props.dashboard))\n return [];\n\n const disableDelete = (\n props.dashboard.status === DashboardStatus.Published &&\n props.dashboard.widgets.length === 1\n );\n\n const deleteAction: DropdownActionOptions = {\n label: 'Delete',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.DELETE_WIDGET,\n args: [props.id]\n },\n className: `btn btn-link text-danger ${disableDelete ? `disabled cursor-default ${styles.disabledAction}` : ''}`,\n disabled: disableDelete,\n tooltip: disableDelete ? 'Published dashboards must have at least 1 widget' : ''\n };\n\n if (props.isReadOnlyWidget)\n return [deleteAction];\n\n return [\n {\n label: 'Edit content',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.WIZARD_EDIT_CONTENT,\n args: [ props.dashboardId, props.id, props.widgetId, props.templateId ]\n },\n className: 'btn btn-link'\n },\n deleteAction\n ];\n }\n\n const templateName = WidgetTemplateConfig[props.templateId].displayName ??\n props.templates?.find(t => t.id === props.templateId).name;\n\n return (\n <div\n className={`p-3 me-1 border border-secondary rounded-3 ${isDisabled ? 'cursor-default' : 'cursor-grab'} ${isDisabled ? styles.disabled : ''} ${styles.widgetItem}`}\n onClick={handleClick}\n style={props.style}\n ref={ref}\n aria-roledescription='Sortable widget'\n {...props.dragAttributes}\n {...props.dragListeners}\n >\n <DropIndicator dragDirection={props.dragDirection} />\n <div className='d-flex justify-content-between w-100'>\n <div className='d-flex'>\n <div className={styles.numberContainer}>\n <div className={`${styles.widgetNumber} mx-auto text-center h6`}>\n <strong>{props.index + 1}</strong>\n </div>\n <SvgContainer\n svg={props.dragHandleIcon}\n size={props.dragHandleIconSize}\n className={styles.widgetHandle}\n />\n </div>\n <div className='ps-2'>\n <DashboardWidgetIcon id={props.widgetId} />\n </div>\n <div className='ps-2 fw-semibold'>{templateName}</div>\n </div>\n <div id={toggleId} className={styles.widgetActions} onClick={handleClick}>\n <ActionsDropdown actions={getActions()} dropdownToggleClassName='border-0 bg-transparent' />\n </div>\n </div>\n <div className={`pt-2 clamp-2 ${props.headingClassName || ''}`} title={props.name}><strong>{props.name}</strong></div>\n <div className='pt-2'>\n <SvgContainer className={`${styles.svgContainer}`} svg={WidgetTemplateConfig[props.templateId].icon} />\n </div>\n </div>\n );\n }\n);\n",":local {\n $top-nav-height: 2.5rem;\n $footer-height: 30px;\n\n .itemListWrapper {\n height: calc(100vh - (#{$top-nav-height} + #{$footer-height}));\n }\n\n .header {\n position: sticky;\n top: 0;\n z-index: 3;\n }\n}","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport { DragEndEvent } from '@dnd-kit/core';\n\nimport { IconButton } from 'libs/shared/components/icon-button/IconButton';\nimport { SortableContainerWrapper } from 'libs/shared/components/sortable/SortableContainerWrapper';\nimport { SortableItemWrapper } from 'libs/shared/components/sortable/SortableItemWrapper';\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { Tooltip } from 'libs/shared/components/tooltip/Tooltip';\nimport { DragOverlayStyles } from 'libs/shared/constants/DragOverlayStyles';\nimport { WidgetTemplateConfig } from 'libs/shared/constants/WidgetTemplateConfig';\nimport { PlusSvg } from 'libs/shared/images/svg/actions/PlusSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus } from 'libs/shared/interfaces';\nimport { SvgIcon } from 'libs/shared/utils/SvgHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { WidgetEditorItem } from 'apps/dashboard-editor/components/widget-editor-item/WidgetEditorItem';\n\nimport styles from './widget-editor-list.module.scss';\n\nexport interface WidgetEditorListProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n templates: CuratedWidgetTemplate[];\n startingPositionIndex?: number;\n}\n\ninterface SortableWidgetEditorListProps extends WidgetEditorListProps {\n dragHandleIcon: SvgIcon;\n dragHandleIconSize: SvgContainerSize;\n onSortEnd: (event: DragEndEvent) => void;\n currentSortingIndex?: number;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function SortableWidgetEditorList(props: SortableWidgetEditorListProps): JSX.Element {\n function getDragOverlay(id: string) {\n const widgetIndex = props.widgets.findIndex(widget => widget.id === id);\n const widget = props.widgets[widgetIndex];\n\n return (\n <WidgetEditorItem\n index={widgetIndex}\n templates={props.templates}\n dragHandleIcon={props.dragHandleIcon}\n dragHandleIconSize={props.dragHandleIconSize}\n style={DragOverlayStyles}\n setScrollToWidgetId={props.setScrollToWidget}\n dashboard={props.dashboard}\n {...widget}\n />\n );\n }\n\n function getCreateTooltip(): string {\n if (props.dashboard.status === DashboardStatus.Archived)\n return 'Archived dashboards cannot be edited';\n\n if (props.dashboard.status === DashboardStatus.Published)\n return 'Published dashboards cannot be edited. Please create a copy to make any changes.';\n\n return '';\n }\n\n const isDisabled = !DashboardHelper.canEdit(props.dashboard);\n\n return (\n <div className='position-relative'>\n <div className={`bg-white border-bottom ${styles.header}`}>\n <div className='d-flex justify-content-between align-items-center p-2 me-1'>\n <h2 className='h5 mb-0'>Content</h2>\n <Tooltip title={getCreateTooltip()} placement='right' spanHack>\n <IconButton\n className='btn btn-dark'\n svg={PlusSvg}\n appLink={{\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.WIZARD_SELECT_WIDGET,\n args: [props.dashboard.id]\n }}\n disabled={isDisabled}\n />\n </Tooltip>\n </div>\n </div>\n\n <SortableContainerWrapper\n ids={props.widgets.map(w => w.id)}\n getDragOverlay={getDragOverlay}\n onSortEnd={props.onSortEnd}\n dropAnimation={{ duration: 100 }}\n disabled={isDisabled}\n >\n <div className={`${styles.itemListWrapper}`}>\n <Scrollbars>\n <ol className='list-unstyled px-2 pb-2 mb-0'>\n {props.widgets.filter(w => WidgetTemplateConfig[w.templateId]).map((widget, idx) => {\n let heading = widget.name || '';\n let headingClassName = '';\n\n if (!heading) {\n heading = 'No heading';\n headingClassName = 'fst-italic';\n }\n\n const isReadOnlyWidget = DashboardHelper.isWidgetReadonly(widget);\n\n return (\n <li className='pb-3' key={widget.id}>\n <SortableItemWrapper\n id={widget.id}\n disabled={isReadOnlyWidget}\n childComponent={WidgetEditorItem}\n childProps={{\n ...widget,\n name: heading,\n headingClassName,\n index: idx,\n templates: props.templates,\n dragHandleIcon: props.dragHandleIcon,\n dragHandleIconSize: props.dragHandleIconSize,\n setScrollToWidgetId: props.setScrollToWidget,\n dashboard: props.dashboard,\n isReadOnlyWidget\n }}\n />\n </li>\n );\n })}\n </ol>\n </Scrollbars>\n </div>\n </SortableContainerWrapper>\n \n </div>\n );\n}\n","import React from 'react';\nimport { DragEndEvent } from '@dnd-kit/core';\n\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { SvgContainerSize } from 'libs/shared/components/svg-container/SvgContainer';\nimport { HandleSvg } from 'libs/shared/images/svg/objects/HandleSvg';\n\nimport { SortableWidgetEditorList, WidgetEditorListProps } from 'apps/dashboard-editor/components/widget-editor-list/WidgetEditorList';\n\ninterface SortableWidgetEditorListContainerProps extends WidgetEditorListProps {\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function SortableWidgetEditorListContainer(props: SortableWidgetEditorListContainerProps): React.ReactElement {\n const { onSortComplete, ...widgetListProps } = props;\n\n const onSortEnd = (event: DragEndEvent) => {\n const oldIndex = ArrayHelper.findMatchedIdIndex(props.widgets, event.active.id);\n const newIndex = ArrayHelper.findMatchedIdIndex(props.widgets, event.over.id);\n\n onSortComplete(oldIndex, newIndex);\n };\n\n return (\n <SortableWidgetEditorList\n {...widgetListProps}\n onSortEnd={onSortEnd}\n dragHandleIcon={HandleSvg}\n dragHandleIconSize={SvgContainerSize.ExtraSmall}\n setScrollToWidget={props.setScrollToWidget}\n />\n );\n}\n",":local {\n $top-nav-height: 2.5rem;\n $footer-height: 30px;\n $editor-list-width: 16rem;\n\n .contentWrapper {\n max-height: calc(100vh - (#{$top-nav-height} + #{$footer-height}));\n }\n\n .scrollbarTrack {\n position: absolute; \n width: 0.375rem; \n right: 0.125rem; \n bottom: 0.125rem; \n top: 0.125rem;\n border-radius: 0.1875rem; \n z-index: 5;\n }\n\n .widgetEditorListColumn {\n width: $editor-list-width;\n min-height: calc(100vh - #{$top-nav-height});\n position: absolute;\n left: 0;\n top: $top-nav-height;\n }\n\n .dashboardEditorPreview {\n margin-left: $editor-list-width;\n min-height: calc(100vh - (#{$top-nav-height} + #{$footer-height}));\n }\n}","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { Core } from 'libs/common/backbone/index';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { Classification, CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\nimport { TopicsHelper } from 'libs/shared/utils/topics-helper/TopicsHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\n\nimport { PresentationRequests } from 'apps/cv-live/flight-requests/CvLivePresentationRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\nconst namespace = 'dashboardEditor.editClassificationDashboardView';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\ninterface EditClassificationDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditClassificationDashboardView(props: EditClassificationDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n let classificationId: string;\n if (CuratedDashboardHelper.isClassificationDashboard(targetInfo))\n classificationId = targetInfo.classificationId;\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const classification = Flight.useBasicFetch<Classification>(classificationId &&\n SubjectRequests.classification(classificationId));\n\n const presentation = Flight.useBasicFetch<Presentation>(\n classification.hasCompleted &&\n SubjectRequests.presentation(classification.data.presentationId)\n );\n\n const cvLivePresentation = Flight.useBasicFetch<Presentation>(\n PresentationRequests.cvLivePresentation()\n );\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n presentation.hasCompleted &&\n AudienceRequests.audiencesByPresentationId(presentation.data?.id)\n );\n\n const availablePresentations = Flight.useBasicFetch<Presentation[]>(\n ClassificationRequests.availablePresentations(PresentationType.Subject)\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n\n const path = Flight.useBasicFetch<Classification[]>(\n classificationId && ClassificationRequests.path(classificationId)\n );\n const isStreamable = +presentation.data?.id === +cvLivePresentation.data?.id;\n\n function getBreadcrumbs(): Breadcrumb[] {\n const breadcrumbs: Breadcrumb[] = [{\n name: getPhrase('discover')\n }, {\n name: TopicsHelper.getExploreAllTopicsBreadcrumb(presentation.data?.name, availablePresentations.data?.length)\n }];\n\n path.data.forEach(item => {\n breadcrumbs.push({\n name: item.name,\n active: item.name === classification.data.name\n });\n });\n\n return breadcrumbs;\n }\n\n function getPreviewUrl(): string {\n let baseUrl = '';\n if (isStreamable) {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.StreamableUrl,\n `topics/${classification.data.id}/${TextHelper.slugify(classification.data.name)}`\n );\n } else {\n const isDirectory = CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.ClassificationDirectory);\n\n if (isDirectory) {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `topics/${classification.data.id}/${TextHelper.slugify(classification.data.name)}/topics`\n );\n } else {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `topics/${classification.data.id}/${TextHelper.slugify(classification.data.name)}`\n );\n }\n }\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getCloseAppLink(): Core.AppLink {\n if (isStreamable) {\n return {\n application: AppChannels.CV_LIVE,\n action: Actions.CvLive.EDIT_CLASSIFICATION_DASHBOARDS,\n args: [ presentation.data.id, classification.data.id ]\n };\n }\n\n return CuratedDashboardHelper.isType(props.dashboard, DashboardTargetType.Classification) ?\n {\n application: AppChannels.SUBJECTS,\n action: Actions.Subjects.EDIT_CLASSIFICATION_DASHBOARDS,\n args: [ presentation.data.id, classification.data.id ]\n } : {\n application: AppChannels.SUBJECTS,\n action: Actions.Subjects.EDIT_CLASSIFICATION_DIRECTORIES,\n args: [ presentation.data.id, classification.data.id ]\n };\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: getCloseAppLink(),\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n availablePresentations.data &&\n classification.data &&\n path.data &&\n presentation.data &&\n curriculum.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n classification={classification.data}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n getBreadcrumbs={getBreadcrumbs}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.TOPIC_DASHBOARD}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n cvLivePresentation={cvLivePresentation.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { TextHelper } from 'libs/common/react/utils/TextHelper';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { Company, CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { CompanyRequests } from 'apps/companies/flight-requests';\nimport { PresentationRequests } from 'apps/cv-live/flight-requests/CvLivePresentationRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditCompanyDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditCompanyDashboardView(props: EditCompanyDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n let companyId: string;\n let presentationId: string;\n\n if (targetInfo.targetType === DashboardTargetType.Company) {\n companyId = targetInfo.companyId;\n presentationId = targetInfo.presentationId;\n }\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n AudienceRequests.audiencesByPresentationId(presentationId)\n );\n\n const presentation = Flight.useBasicFetch<Presentation>(\n SubjectRequests.presentation(presentationId)\n );\n\n const cvLivePresentation = Flight.useBasicFetch<Presentation>(\n PresentationRequests.cvLivePresentation()\n );\n\n const company = Flight.useBasicFetch<Company>(\n CompanyRequests.getCompany(companyId)\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n const isStreamable = DashboardHelper.isProduct(\n props.dashboard,\n ProductId.StreamableLearning,\n cvLivePresentation.data?.id\n );\n\n function getPreviewUrl(): string {\n let baseUrl = '';\n if (isStreamable) {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.StreamableUrl,\n `/partners/${companyId}/${TextHelper.slugify(company.data.name)}`\n );\n } else {\n baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `/studios/${companyId}/${TextHelper.slugify(company.data.name)}`\n );\n }\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n presentationId: presentation.data?.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getBreadcrumbs(): Breadcrumb[] {\n if (!company.hasCompleted)\n return [];\n\n return [{\n name: isStreamable ? 'Discover' : 'Movies + TV'\n }, {\n name: company.data.name,\n active: true\n }];\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: isStreamable ? {\n application: AppChannels.CV_LIVE,\n action: Actions.CvLive.EDIT_COMPANY_DASHBOARDS,\n args: [companyId]\n } : {\n application: AppChannels.COMPANIES,\n action: Actions.Companies.EDIT_DASHBOARDS,\n args: [ companyId, presentationId ]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n presentation.data &&\n company.data &&\n curriculum.data &&\n cvLivePresentation.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n company={company.data}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.MOVIES_AND_TV_DASHBOARD}\n moviesAndTvIconUrl={ImageUrls.Dashboard.MOVIES_AND_TV_ICON}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n getBreadcrumbs={getBreadcrumbs}\n cvLivePresentation={cvLivePresentation.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { LocationUtils } from 'libs/common/backbone/core';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { Breadcrumb } from 'libs/shared/components/breadcrumbs/Breadcrumbs';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, PartnerProfile } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\n\nimport { ContentPartnerRequests } from 'apps/content-partners/flight-requests/ContentPartnerRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditContentPartnerDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditContentPartnerDashboardView(props: EditContentPartnerDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n const slug = targetInfo.targetType === DashboardTargetType.PartnerProfile ?\n targetInfo.slug :\n '';\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const contentPartner = Flight.useBasicFetch<PartnerProfile>(\n ContentPartnerRequests.getContentPartnerBySlug(slug)\n );\n\n function getPreviewUrl(): string {\n if (targetInfo.targetType !== DashboardTargetType.PartnerProfile) {\n return '';\n }\n const baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `channels/${targetInfo.slug}`\n );\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getBreadcrumbs(): Breadcrumb[] {\n return [{\n name: 'Discover'\n },\n {\n name: 'Channels'\n },\n {\n name: contentPartner.data.name,\n active: true\n }];\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: {\n application: AppChannels.CONTENT_PARTNERS,\n action: Actions.ContentPartners.CONTENT_PARTNER_DASHBOARDS,\n args: [contentPartner.data.id]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n function onClickSearchAllVideos(): void {\n const baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n `search`\n );\n\n LocationUtils.PageLoad(UrlHelper.urlBuilder(baseUrl, {\n scopeId: contentPartner.data.id\n }), true);\n }\n\n const dataLoaded = contentPartner.data;\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n audiences={[]}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.MOVIES_AND_TV_DASHBOARD}\n scrollToWidgetId={props.scrollToWidget}\n getBreadcrumbs={getBreadcrumbs}\n commonVideoProps={commonVideoProps}\n partnerProfile={contentPartner.data}\n onClickSearchAllVideos={onClickSearchAllVideos}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\nimport { DashboardHelper } from 'shared/utils/DashboardHelper';\n\nimport { PresentationRequests } from 'apps/cv-live/flight-requests/CvLivePresentationRequests';\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditDiscoverDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditDiscoverDashboardView(props: EditDiscoverDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n let presentationId: string;\n if (targetInfo.targetType === DashboardTargetType.Discover)\n presentationId = targetInfo.presentationId;\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n AudienceRequests.audiencesByPresentationId(presentationId)\n );\n const availablePresentations = Flight.useBasicFetch<Presentation[]>(\n ClassificationRequests.availablePresentations(PresentationType.Subject)\n );\n const presentation = Flight.useBasicFetch<Presentation>(\n SubjectRequests.presentation(presentationId)\n );\n const cvLivePresentation = Flight.useBasicFetch<Presentation>(\n PresentationRequests.cvLivePresentation()\n );\n\n const isStreamable = DashboardHelper.isProduct(\n props.dashboard,\n ProductId.StreamableLearning,\n cvLivePresentation.data?.id\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n !isStreamable && ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n\n function getPreviewUrl(): string {\n let baseUrl = '';\n if (isStreamable) {\n baseUrl = ClickView.Config.Urls.StreamableUrl;\n } else {\n baseUrl = ClickView.Config.Urls.LiteUrl;\n }\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n presentationId: presentation.data?.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: isStreamable ? {\n application: AppChannels.CV_LIVE,\n action: Actions.CvLive.DISCOVER\n } : {\n application: AppChannels.DISCOVER,\n action: Actions.Discover.PRESENTATION_DASHBOARDS,\n args: [presentationId]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n availablePresentations.data &&\n presentation.data &&\n (isStreamable || curriculum.data) &&\n cvLivePresentation.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.DISCOVER_DASHBOARD}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n cvLivePresentation={cvLivePresentation.data}\n availablePresentations={availablePresentations.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\nimport { Spinner } from 'react-bootstrap';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\n\nimport { ActionOptions } from 'libs/shared/components/actions/Actions';\nimport { HoverToPortalContainer } from 'libs/shared/components/hover-to-portal-container/HoverToPortalContainer';\nimport { PresentationType } from 'libs/shared/enums/PresentationType';\nimport { AudienceRequests } from 'libs/shared/flight-requests/AudienceRequests';\nimport { ClassificationRequests } from 'libs/shared/flight-requests/ClassificationRequests';\nimport { CloseSvg } from 'libs/shared/images/svg/actions/CloseSvg';\nimport { EditSvg } from 'libs/shared/images/svg/actions/EditSvg';\nimport { VisibleOnSvg } from 'libs/shared/images/svg/actions/VisibleOnSvg';\nimport { CuratedDashboard, CuratedWidget, CuratedWidgetTemplate, DashboardStatus, DashboardTargetType, Presentation, PresentationAudience } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { Actions, AppChannels } from 'shared/constants';\nimport { ImageUrls } from 'shared/constants/ImageUrls';\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { SubjectRequests } from 'shared/flight-requests/SubjectRequests';\nimport { useCommonVideoProps } from 'shared/hooks/UseCommonVideoProps';\n\nimport { DashboardEditorPreview } from 'apps/dashboard-editor/components/dashboard-editor-preview/DashboardEditorPreview';\nimport { DashboardStickyHeader } from 'apps/dashboard-editor/components/dashboard-sticky-header/DashboardStickyHeader';\nimport { LoadingMask } from 'apps/dashboard-editor/components/loading-mask/LoadingMask';\nimport { SortableWidgetEditorListContainer } from 'apps/dashboard-editor/components/widget-editor-list/SortableWidgetEditorListContainer';\n\nimport styles from '../edit-dashboard-view.module.scss';\n\ninterface EditMoviesAndTvDashboardViewProps {\n dashboard: CuratedDashboard;\n widgets: CuratedWidget[];\n showLoadingMask: boolean;\n isSaving: boolean;\n onSortComplete: (oldIdx: number, newIdx: number) => void;\n templates: CuratedWidgetTemplate[];\n scrollToWidget: string;\n setScrollToWidget: (id: string) => void;\n}\n\nexport function EditMoviesAndTvDashboardView(props: EditMoviesAndTvDashboardViewProps): JSX.Element {\n const targetInfo = CuratedDashboardHelper.getDashboardTargetInfo(props.dashboard);\n\n const presentationId = targetInfo.targetType === DashboardTargetType.MoviesAndTv &&\n targetInfo.presentationId;\n\n const { commonVideoProps } = useCommonVideoProps();\n\n const audiences = Flight.useBasicFetch<PresentationAudience[]>(\n AudienceRequests.audiencesByPresentationId(presentationId)\n );\n\n const presentation = Flight.useBasicFetch<Presentation>(\n SubjectRequests.presentation(presentationId)\n );\n\n const curriculum = Flight.useBasicFetch<Presentation>(\n ClassificationRequests.presentation(PresentationType.Curriculum)\n );\n\n function getPreviewUrl(): string {\n const baseUrl = UrlHelper.safeUrlConcat(\n ClickView.Config.Urls.LiteUrl,\n 'movies-and-tv'\n );\n\n return UrlHelper.urlBuilder(baseUrl, {\n dashboardId: props.dashboard.id,\n presentationId: presentation.data?.id,\n preview: true,\n skipPrompt: true\n });\n }\n\n function getActions(status: DashboardStatus): ActionOptions[] {\n return [\n {\n label: status === DashboardStatus.Published ? 'View in product' : 'Preview',\n href: getPreviewUrl(),\n openInNewTab: true,\n button: true,\n svg: VisibleOnSvg,\n className: 'btn btn-outline-dark ms-2',\n disabled: status === DashboardStatus.Archived,\n tooltip: status === DashboardStatus.Archived ? 'Archived dashboards cannot be previewed in product' : ''\n },\n {\n label: 'Edit details',\n appLink: {\n application: AppChannels.DASHBOARD_EDITOR,\n action: Actions.DashboardEditor.EDIT_DASHBOARD_DETAILS,\n args: [props.dashboard.id]\n },\n button: true,\n svg: EditSvg,\n className: 'btn btn-outline-dark ms-2'\n },\n {\n label: '',\n appLink: {\n application: AppChannels.MOVIES_AND_TV,\n action: Actions.MoviesAndTv.MOVIES_AND_TV_DASHBOARD,\n args: [presentationId]\n },\n button: true,\n className: 'btn btn-outline-dark ms-2',\n svg: CloseSvg\n }\n ];\n }\n\n const dataLoaded = (\n audiences.data &&\n presentation.data &&\n curriculum.data\n );\n\n if (!dataLoaded) {\n return (\n <div className='p-5 d-flex justify-content-center align-items-center' style={{ height: '75vh' }}>\n <Spinner as='div' animation='border' role='status' />\n </div>\n );\n }\n\n return (\n <HoverToPortalContainer.ReferenceContainer>\n <div className={`${styles.contentWrapper} d-flex`}>\n <div className={`${styles.widgetEditorListColumn} border-end`}>\n <SortableWidgetEditorListContainer\n dashboard={props.dashboard}\n widgets={props.widgets}\n templates={props.templates}\n onSortComplete={props.onSortComplete}\n setScrollToWidget={props.setScrollToWidget}\n />\n </div>\n\n <div className={`${styles.dashboardEditorPreview} w-100 position-relative pb-3`}>\n <DashboardStickyHeader\n presentation={presentation.data}\n dashboard={props.dashboard}\n isSaving={props.isSaving}\n getActions={() => getActions(props.dashboard.status)}\n />\n\n {props.showLoadingMask && <LoadingMask />}\n\n <Scrollbars renderTrackVertical={() => <div className={styles.scrollbarTrack} />}>\n <DashboardEditorPreview\n dashboard={props.dashboard}\n audiences={audiences.data}\n getWidgetContentRequest={DashboardRequests.widget}\n emptyImageUrl={ImageUrls.EmptyStates.DashboardEditor.MOVIES_AND_TV_DASHBOARD}\n moviesAndTvIconUrl={ImageUrls.Dashboard.MOVIES_AND_TV_ICON}\n scrollToWidgetId={props.scrollToWidget}\n presentation={presentation.data}\n commonVideoProps={commonVideoProps}\n />\n </Scrollbars>\n </div>\n </div>\n </HoverToPortalContainer.ReferenceContainer>\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { ObjectHelper } from 'libs/common/react/utils/ObjectHelper';\n\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\nimport { ClassificationWithChildren, CuratedWidget, CuratedWidgetTemplate, DashboardTargetType, ParentAndChildClassificationsWidgetData } from 'libs/shared/interfaces';\nimport { CuratedDashboardHelper } from 'libs/shared/utils/DashboardHelper';\n\nimport { DashboardRequests } from 'shared/flight-requests/DashboardRequests';\nimport { WidgetRequests } from 'shared/flight-requests/WidgetRequests';\n\nimport { AnimationFinishedBuffer } from 'apps/dashboard-editor/constants/AnimationConstants';\nimport { useFetchDashboard } from 'apps/dashboard-editor/hooks/useFetchDashboard';\nimport { EditClassificationDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-classification-dashboard/EditClassificationDashboardView';\nimport { EditCompanyDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-company-dashboard/EditCompanyDashboardView';\nimport { EditContentPartnerDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-content-partner-dashboard/EditContentPartnerDashboardView';\nimport { EditDiscoverDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-discover-dashboard/EditDiscoverDashboardView';\nimport { EditMoviesAndTvDashboardView } from 'apps/dashboard-editor/views/edit-dashboard/edit-movies-and-tv-dashboard/EditMoviesAndTvDashboardView';\n\nlet timerId: number = 0;\nconst WIDGET_HIGHLIGHT_ANIMATION_TIMER = 4500; // Animation time in ms\n\ninterface EditDashboardContainerViewProps {\n id: string;\n}\n\nexport function EditDashboardContainerView(props: EditDashboardContainerViewProps): JSX.Element {\n const [ widgets, setWidgets ] = React.useState<CuratedWidget[]>([]);\n const [ showLoadingMask, setShowLoadingMask ] = React.useState(false);\n const [ scrollToWidget, setScrollToWidget ] = React.useState('');\n\n const dashboard = useFetchDashboard(props.id);\n\n const templates = Flight.useBasicFetch<CuratedWidgetTemplate[]>(DashboardRequests.templates());\n\n const fetch = Flight.useGetFetch();\n\n useSetPageMetadata({ title: dashboard.data?.name });\n\n React.useEffect(() => {\n document.body.style.overflowY = 'hidden';\n return () => {\n document.body.style.overflowY = 'auto';\n };\n }, []);\n\n const formattedWidgets = dashboard.data?.widgets.map(w => {\n if (w.data.classifications) {\n return {\n ...w,\n data: {\n ...w.data,\n // only pass required fields: id and options\n classifications: [ObjectHelper.pick(w.data.classifications[0], [ 'id', 'options' ]) as ClassificationWithChildren]\n } as ParentAndChildClassificationsWidgetData\n };\n }\n\n return w;\n });\n\n function onSortComplete(oldIdx: number, newIdx: number): void {\n if (oldIdx === newIdx) {\n return;\n }\n \n const oldWidgets = formattedWidgets;\n if (!oldWidgets[oldIdx] || !oldWidgets[newIdx]) {\n return;\n }\n\n const reorderedWidgets = ArrayHelper.moveItem(oldWidgets, oldIdx, newIdx).map((widget, index) => ({\n ...widget,\n index\n }));\n\n setWidgets(reorderedWidgets);\n setShowLoadingMask(true);\n\n fetch(WidgetRequests.sortWidgets(\n reorderedWidgets.map(widget => ObjectHelper.omit(widget, ['content'])),\n dashboard.data,\n null,\n // Rollback when error occurs\n () => setWidgets(oldWidgets),\n () => window.setTimeout(() => setShowLoadingMask(false), AnimationFinishedBuffer)\n ));\n }\n\n React.useEffect(() => {\n if (!scrollToWidget)\n return;\n\n // Reset any existing timer in case the user clicks on more than 1 widget in a row\n if (timerId)\n window.clearTimeout(timerId);\n\n timerId = window.setTimeout(() => {\n setScrollToWidget('');\n }, WIDGET_HIGHLIGHT_ANIMATION_TIMER);\n }, [scrollToWidget]);\n\n React.useEffect(() => {\n if (!dashboard.hasCompleted)\n return;\n\n setWidgets(dashboard.data.widgets);\n }, [ dashboard.data, dashboard.hasCompleted ]);\n\n if (!dashboard.data)\n return <></>;\n\n // TODO: Properly handle errors\n if (dashboard.hasError)\n return <>Error</>;\n\n const isSaving = showLoadingMask || (dashboard.hasCompleted && dashboard.isFetching);\n\n const commonProps = {\n dashboard: dashboard.data,\n widgets: widgets,\n isSaving: isSaving,\n showLoadingMask: showLoadingMask,\n onSortComplete: onSortComplete,\n templates: templates.data,\n scrollToWidget: scrollToWidget,\n setScrollToWidget: setScrollToWidget\n };\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.Discover))\n return <EditDiscoverDashboardView {...commonProps} />;\n\n if (CuratedDashboardHelper.isClassificationDashboard(\n CuratedDashboardHelper.getDashboardTargetInfo(dashboard.data)\n )) {\n return <EditClassificationDashboardView {...commonProps} />;\n }\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.MoviesAndTv))\n return <EditMoviesAndTvDashboardView {...commonProps} />;\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.Company))\n return <EditCompanyDashboardView {...commonProps} />;\n\n if (CuratedDashboardHelper.isType(dashboard.data, DashboardTargetType.PartnerProfile))\n return <EditContentPartnerDashboardView {...commonProps} />;\n\n return <></>;\n}\n"],"mappings":"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"}