@clickview/reports 0.90.0-rc.1 → 0.90.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/.vite/manifest.json +200 -200
  2. package/dist/bundles.json +1 -1
  3. package/dist/en.json +1 -1
  4. package/dist/scripts/{D_FEtk4z.chunk.js → 4ViYfbV7.chunk.js} +2 -2
  5. package/dist/scripts/{D_FEtk4z.chunk.js.map → 4ViYfbV7.chunk.js.map} +1 -1
  6. package/dist/scripts/{CkUPoXTo.chunk.js → 4gz8eG_F.chunk.js} +2 -2
  7. package/dist/scripts/{CkUPoXTo.chunk.js.map → 4gz8eG_F.chunk.js.map} +1 -1
  8. package/dist/scripts/{DNagXaPV2.chunk.js → 4mtEyuqT2.chunk.js} +2 -2
  9. package/dist/scripts/{DNagXaPV2.chunk.js.map → 4mtEyuqT2.chunk.js.map} +1 -1
  10. package/dist/scripts/{CPrWMnN-.chunk.js → 7M6FzdyD.chunk.js} +2 -2
  11. package/dist/scripts/{CPrWMnN-.chunk.js.map → 7M6FzdyD.chunk.js.map} +1 -1
  12. package/dist/scripts/{D3Pl0-fQ.chunk.js → BJOOjdj2.chunk.js} +2 -2
  13. package/dist/scripts/{D3Pl0-fQ.chunk.js.map → BJOOjdj2.chunk.js.map} +1 -1
  14. package/dist/scripts/{B9ojUSnp2.chunk.js → BL1X9vs52.chunk.js} +2 -2
  15. package/dist/scripts/{B9ojUSnp2.chunk.js.map → BL1X9vs52.chunk.js.map} +1 -1
  16. package/dist/scripts/{BN2Jc0_B.chunk.js → BLzRzOyq.chunk.js} +2 -2
  17. package/dist/scripts/{BN2Jc0_B.chunk.js.map → BLzRzOyq.chunk.js.map} +1 -1
  18. package/dist/scripts/{CNihWz772.chunk.js → BU8DxGLM2.chunk.js} +2 -2
  19. package/dist/scripts/{CNihWz772.chunk.js.map → BU8DxGLM2.chunk.js.map} +1 -1
  20. package/dist/scripts/{B-CXShcb2.chunk.js → BXWs2cI72.chunk.js} +2 -2
  21. package/dist/scripts/{B-CXShcb2.chunk.js.map → BXWs2cI72.chunk.js.map} +1 -1
  22. package/dist/scripts/{Re7SHmEB2.chunk.js → Bl13dT192.chunk.js} +2 -2
  23. package/dist/scripts/{Re7SHmEB2.chunk.js.map → Bl13dT192.chunk.js.map} +1 -1
  24. package/dist/scripts/{CBswLW82.chunk.js → Bzx4bLV8.chunk.js} +2 -2
  25. package/dist/scripts/{CBswLW82.chunk.js.map → Bzx4bLV8.chunk.js.map} +1 -1
  26. package/dist/scripts/{4QdmE5x_2.chunk.js → CKKR2-wU2.chunk.js} +2 -2
  27. package/dist/scripts/{4QdmE5x_2.chunk.js.map → CKKR2-wU2.chunk.js.map} +1 -1
  28. package/dist/scripts/{s20CYII_2.chunk.js → CcjJpEaF2.chunk.js} +2 -2
  29. package/dist/scripts/{s20CYII_2.chunk.js.map → CcjJpEaF2.chunk.js.map} +1 -1
  30. package/dist/scripts/{B-DINEq3.chunk.js → Ch4Y5yk4.chunk.js} +2 -2
  31. package/dist/scripts/{B-DINEq3.chunk.js.map → Ch4Y5yk4.chunk.js.map} +1 -1
  32. package/dist/scripts/{DqAzhF3o.chunk.js → CitsW6ql.chunk.js} +2 -2
  33. package/dist/scripts/{DqAzhF3o.chunk.js.map → CitsW6ql.chunk.js.map} +1 -1
  34. package/dist/scripts/{iTyahUCH2.chunk.js → CowQEpZQ2.chunk.js} +2 -2
  35. package/dist/scripts/{iTyahUCH2.chunk.js.map → CowQEpZQ2.chunk.js.map} +1 -1
  36. package/dist/scripts/{DxrgOF1-.chunk.js → D2gRMPGY.chunk.js} +2 -2
  37. package/dist/scripts/{DxrgOF1-.chunk.js.map → D2gRMPGY.chunk.js.map} +1 -1
  38. package/dist/scripts/{BabEuLsF2.chunk.js → DDS7ndOq2.chunk.js} +2 -2
  39. package/dist/scripts/{BabEuLsF2.chunk.js.map → DDS7ndOq2.chunk.js.map} +1 -1
  40. package/dist/scripts/{_gzWinH7.chunk.js → DE24b7R6.chunk.js} +2 -2
  41. package/dist/scripts/{_gzWinH7.chunk.js.map → DE24b7R6.chunk.js.map} +1 -1
  42. package/dist/scripts/{CYgv1ISo2.chunk.js → DNY9inGn2.chunk.js} +2 -2
  43. package/dist/scripts/{CYgv1ISo2.chunk.js.map → DNY9inGn2.chunk.js.map} +1 -1
  44. package/dist/scripts/{DQY7SaMp2.chunk.js → DPJbiCR02.chunk.js} +3 -3
  45. package/dist/scripts/{DQY7SaMp2.chunk.js.map → DPJbiCR02.chunk.js.map} +1 -1
  46. package/dist/scripts/{BuFRt1UM.chunk.js → DWQdiwUw.chunk.js} +2 -2
  47. package/dist/scripts/{BuFRt1UM.chunk.js.map → DWQdiwUw.chunk.js.map} +1 -1
  48. package/dist/scripts/{DzTraroE2.chunk.js → DbSzdDBS2.chunk.js} +2 -2
  49. package/dist/scripts/{DzTraroE2.chunk.js.map → DbSzdDBS2.chunk.js.map} +1 -1
  50. package/dist/scripts/{NiiRK9j-2.chunk.js → Dj87pb142.chunk.js} +2 -2
  51. package/dist/scripts/{NiiRK9j-2.chunk.js.map → Dj87pb142.chunk.js.map} +1 -1
  52. package/dist/scripts/{DSNTuwQi2.chunk.js → EvtCZWZL2.chunk.js} +2 -2
  53. package/dist/scripts/{DSNTuwQi2.chunk.js.map → EvtCZWZL2.chunk.js.map} +1 -1
  54. package/dist/scripts/{Cdbg16A92.chunk.js → PSwC3iEf2.chunk.js} +2 -2
  55. package/dist/scripts/{Cdbg16A92.chunk.js.map → PSwC3iEf2.chunk.js.map} +1 -1
  56. package/dist/scripts/{B3UVC04b.chunk.js → TzLygaBE.chunk.js} +2 -2
  57. package/dist/scripts/{B3UVC04b.chunk.js.map → TzLygaBE.chunk.js.map} +1 -1
  58. package/dist/scripts/{app-jxJcaenU.js → app-B1NVV4PT.js} +3 -3
  59. package/dist/scripts/{app-jxJcaenU.js.map → app-B1NVV4PT.js.map} +1 -1
  60. package/dist/scripts/{CsoT7dzm.chunk.js → fh6sbun-.chunk.js} +2 -2
  61. package/dist/scripts/{CsoT7dzm.chunk.js.map → fh6sbun-.chunk.js.map} +1 -1
  62. package/dist/scripts/{s1EOR8_G2.chunk.js → kAYY_iVY2.chunk.js} +2 -2
  63. package/dist/scripts/{s1EOR8_G2.chunk.js.map → kAYY_iVY2.chunk.js.map} +1 -1
  64. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- import{Dr as e,H as t,N as n,at as r}from"./CrTgNROp.chunk.js";import{n as i}from"./CxNc1BDX.chunk.js";import{n as a}from"./Dwe-4MVf.chunk.js";import{t as o}from"./Dsv_eF8a.chunk.js";import{t as s}from"./BIVEB8w0.chunk.js";import{L as c,Q as l,R as u,Z as d,at as f,c as p,lt as m,o as h}from"./app-jxJcaenU.js";import{t as g}from"./B0BRYUl5.chunk.js";import{t as _}from"./CYgv1ISo2.chunk.js";var v=e(r(),1),y=n(),b=`reportsDefault.classroomSizeSelector`,x=10,S=40;function C(e){return(0,y.jsxs)(`div`,{className:i(`border rounded-3 p-3`,e.className),children:[(0,y.jsx)(`h3`,{className:`h6 fw-semibold mb-1`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeTitle`})}),(0,y.jsx)(`p`,{className:`text-secondary mb-3`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeDescription`})}),(0,y.jsx)(`label`,{className:`mb-1`,htmlFor:`classroomSize`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeLabel`})}),(0,y.jsx)(m.Range,{id:`classroomSize`,min:x,max:S,step:1,value:e.classroomSize,onChange:t=>e.onClassroomSizeChanged(Number(t.target.value))}),(0,y.jsxs)(`div`,{className:`d-flex justify-content-between small mb-2`,children:[(0,y.jsx)(`span`,{children:x}),(0,y.jsx)(`span`,{children:S})]}),(0,y.jsx)(`p`,{className:`text-secondary mb-0`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeSummary`,options:{count:e.classroomSize}})})]})}var w=`reportsDefault.classroomViewsToggle`;function T(e){return(0,y.jsxs)(`div`,{className:i(`border rounded-3 p-3 d-flex align-items-center gap-3`,e.className),children:[(0,y.jsxs)(`div`,{className:`flex-grow-1`,children:[(0,y.jsx)(`h3`,{className:`h6 fw-semibold mb-1`,children:(0,y.jsx)(a,{namespace:w,phrase:`title`})}),(0,y.jsx)(`p`,{className:`text-secondary mb-0`,children:(0,y.jsx)(a,{namespace:w,phrase:`description`})})]}),(0,y.jsx)(l,{on:e.enabled,floatEnd:!1,onClick:()=>e.onEnabledChanged(!e.enabled)})]})}var E=`reportsDefault.schoolHoursSelector`,D=[6,7,8,9,10,11,12,13,14,15,16,17,18],O=p.getTimezones();function k(e){let[t,n]=v.useState(!1),r=e.startHour<e.endHour;return(0,y.jsxs)(`div`,{className:i(`border rounded-3 p-3`,e.className),children:[(0,y.jsx)(`h3`,{className:`h6 fw-semibold mb-1`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursTitle`})}),(0,y.jsx)(`p`,{className:`text-secondary mb-3`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursDescription`})}),(0,y.jsxs)(`div`,{className:`d-flex align-items-end gap-3 mb-2`,children:[(0,y.jsxs)(`div`,{className:`flex-grow-1`,children:[(0,y.jsx)(`label`,{className:`small mb-1 d-block`,children:(0,y.jsx)(a,{namespace:E,phrase:`startTimeLabel`})}),(0,y.jsx)(`select`,{className:`form-select`,value:e.startHour,onChange:t=>e.onStartHourChanged(Number(t.target.value)),children:D.map(e=>(0,y.jsx)(`option`,{value:e,children:o.hourToFriendlyString(e)},e))})]}),(0,y.jsx)(`span`,{className:`pb-2`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursTo`})}),(0,y.jsxs)(`div`,{className:`flex-grow-1`,children:[(0,y.jsx)(`label`,{className:`small mb-1 d-block`,children:(0,y.jsx)(a,{namespace:E,phrase:`endTimeLabel`})}),(0,y.jsx)(`select`,{className:`form-select`,value:e.endHour,onChange:t=>e.onEndHourChanged(Number(t.target.value)),children:D.map(e=>(0,y.jsx)(`option`,{value:e,children:o.hourToFriendlyString(e)},e))})]})]}),r?(0,y.jsx)(`p`,{className:`text-secondary mb-0`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursSummary`,options:{startTime:o.hourToFriendlyString(e.startHour),endTime:o.hourToFriendlyString(e.endHour)}})}):(0,y.jsx)(`p`,{className:`text-danger mb-0`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursValidation`})}),(0,y.jsx)(`div`,{className:`mt-3`,children:t?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(`label`,{className:`mb-1 d-block`,children:(0,y.jsx)(a,{namespace:E,phrase:`timezoneLabel`})}),(0,y.jsx)(`select`,{className:`form-select`,value:e.timezone,onChange:t=>e.onTimezoneChanged(t.target.value),children:O.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))})]}):(0,y.jsxs)(`span`,{className:`text-secondary`,children:[(0,y.jsx)(a,{namespace:E,phrase:`timezoneCurrent`,options:{timezone:e.timezone}}),` — `,(0,y.jsx)(`button`,{className:`btn btn-link text-info p-0 align-baseline`,onClick:()=>n(!0),children:(0,y.jsx)(a,{namespace:E,phrase:`timezoneChange`})})]})})]})}var A=`reports.classroomViewsPopup`,j=s.encloseNamespace(A);function M(e){let n=h(t.ClassroomViewsPopup),{enableAlert:r}=_(n.hasClassroomViews),i=g(),s=o.timeStringToHour(n.schoolStartTime),l=o.timeStringToHour(n.schoolEndTime),[p,m]=v.useState(n.hasClassroomViews),[b,x]=v.useState(n.classroomSize),[S,w]=v.useState(n.timezone),[E,D]=v.useState(s),[O,M]=v.useState(l),[N,P]=v.useState(!1),F=!p||E<O&&S,I=p!==n.hasClassroomViews||b!==n.classroomSize||S!==n.timezone||E!==s||O!==l;async function L(){try{P(!0),await n.updateSettingsAsync({hasClassroomViews:p,schoolStartTime:o.hourToTimeString(E),schoolEndTime:o.hourToTimeString(O),timezone:S,classroomSize:b}),i.success(j(`success`)),p||r(),e.closePopup()}catch{i.error(j(`error`))}finally{P(!1)}}return(0,y.jsxs)(f,{closePopup:e.closePopup,title:j(`title`),size:`lg`,children:[(0,y.jsx)(`p`,{children:(0,y.jsx)(a,{namespace:A,phrase:`description1`})}),(0,y.jsx)(`p`,{children:(0,y.jsx)(a,{namespace:A,phrase:`description2`})}),(0,y.jsx)(T,{className:`my-3`,enabled:p,onEnabledChanged:m}),p&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(C,{className:`mb-3`,classroomSize:b,onClassroomSizeChanged:x}),(0,y.jsx)(k,{className:`mb-3`,startHour:E,endHour:O,timezone:S,onStartHourChanged:D,onEndHourChanged:M,onTimezoneChanged:w})]}),(0,y.jsxs)(d,{className:`justify-content-between`,children:[(0,y.jsx)(`a`,{href:c.getLiteArticle(u.ClassroomViews),target:`_blank`,rel:`noopener noreferrer`,className:`text-info`,children:(0,y.jsx)(a,{namespace:A,phrase:`learnMore`})}),(0,y.jsxs)(`div`,{className:`d-flex`,children:[(0,y.jsx)(d.Cancel,{onClick:e.closePopup,text:j(`close`)}),(0,y.jsx)(d.Submit,{onClick:L,text:j(`save`),showSpinner:N,variant:`dark`,disabled:!F||!I})]})]})]})}export{M as ClassroomViewsPopupView};
2
- //# sourceMappingURL=DzTraroE2.chunk.js.map
1
+ import{Dr as e,H as t,N as n,at as r}from"./CrTgNROp.chunk.js";import{n as i}from"./CxNc1BDX.chunk.js";import{n as a}from"./Dwe-4MVf.chunk.js";import{t as o}from"./Dsv_eF8a.chunk.js";import{t as s}from"./BIVEB8w0.chunk.js";import{L as c,Q as l,R as u,Z as d,at as f,c as p,lt as m,o as h}from"./app-B1NVV4PT.js";import{t as g}from"./B0BRYUl5.chunk.js";import{t as _}from"./DNY9inGn2.chunk.js";var v=e(r(),1),y=n(),b=`reportsDefault.classroomSizeSelector`,x=10,S=40;function C(e){return(0,y.jsxs)(`div`,{className:i(`border rounded-3 p-3`,e.className),children:[(0,y.jsx)(`h3`,{className:`h6 fw-semibold mb-1`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeTitle`})}),(0,y.jsx)(`p`,{className:`text-secondary mb-3`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeDescription`})}),(0,y.jsx)(`label`,{className:`mb-1`,htmlFor:`classroomSize`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeLabel`})}),(0,y.jsx)(m.Range,{id:`classroomSize`,min:x,max:S,step:1,value:e.classroomSize,onChange:t=>e.onClassroomSizeChanged(Number(t.target.value))}),(0,y.jsxs)(`div`,{className:`d-flex justify-content-between small mb-2`,children:[(0,y.jsx)(`span`,{children:x}),(0,y.jsx)(`span`,{children:S})]}),(0,y.jsx)(`p`,{className:`text-secondary mb-0`,children:(0,y.jsx)(a,{namespace:b,phrase:`classroomSizeSummary`,options:{count:e.classroomSize}})})]})}var w=`reportsDefault.classroomViewsToggle`;function T(e){return(0,y.jsxs)(`div`,{className:i(`border rounded-3 p-3 d-flex align-items-center gap-3`,e.className),children:[(0,y.jsxs)(`div`,{className:`flex-grow-1`,children:[(0,y.jsx)(`h3`,{className:`h6 fw-semibold mb-1`,children:(0,y.jsx)(a,{namespace:w,phrase:`title`})}),(0,y.jsx)(`p`,{className:`text-secondary mb-0`,children:(0,y.jsx)(a,{namespace:w,phrase:`description`})})]}),(0,y.jsx)(l,{on:e.enabled,floatEnd:!1,onClick:()=>e.onEnabledChanged(!e.enabled)})]})}var E=`reportsDefault.schoolHoursSelector`,D=[6,7,8,9,10,11,12,13,14,15,16,17,18],O=p.getTimezones();function k(e){let[t,n]=v.useState(!1),r=e.startHour<e.endHour;return(0,y.jsxs)(`div`,{className:i(`border rounded-3 p-3`,e.className),children:[(0,y.jsx)(`h3`,{className:`h6 fw-semibold mb-1`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursTitle`})}),(0,y.jsx)(`p`,{className:`text-secondary mb-3`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursDescription`})}),(0,y.jsxs)(`div`,{className:`d-flex align-items-end gap-3 mb-2`,children:[(0,y.jsxs)(`div`,{className:`flex-grow-1`,children:[(0,y.jsx)(`label`,{className:`small mb-1 d-block`,children:(0,y.jsx)(a,{namespace:E,phrase:`startTimeLabel`})}),(0,y.jsx)(`select`,{className:`form-select`,value:e.startHour,onChange:t=>e.onStartHourChanged(Number(t.target.value)),children:D.map(e=>(0,y.jsx)(`option`,{value:e,children:o.hourToFriendlyString(e)},e))})]}),(0,y.jsx)(`span`,{className:`pb-2`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursTo`})}),(0,y.jsxs)(`div`,{className:`flex-grow-1`,children:[(0,y.jsx)(`label`,{className:`small mb-1 d-block`,children:(0,y.jsx)(a,{namespace:E,phrase:`endTimeLabel`})}),(0,y.jsx)(`select`,{className:`form-select`,value:e.endHour,onChange:t=>e.onEndHourChanged(Number(t.target.value)),children:D.map(e=>(0,y.jsx)(`option`,{value:e,children:o.hourToFriendlyString(e)},e))})]})]}),r?(0,y.jsx)(`p`,{className:`text-secondary mb-0`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursSummary`,options:{startTime:o.hourToFriendlyString(e.startHour),endTime:o.hourToFriendlyString(e.endHour)}})}):(0,y.jsx)(`p`,{className:`text-danger mb-0`,children:(0,y.jsx)(a,{namespace:E,phrase:`schoolHoursValidation`})}),(0,y.jsx)(`div`,{className:`mt-3`,children:t?(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(`label`,{className:`mb-1 d-block`,children:(0,y.jsx)(a,{namespace:E,phrase:`timezoneLabel`})}),(0,y.jsx)(`select`,{className:`form-select`,value:e.timezone,onChange:t=>e.onTimezoneChanged(t.target.value),children:O.map(e=>(0,y.jsx)(`option`,{value:e,children:e},e))})]}):(0,y.jsxs)(`span`,{className:`text-secondary`,children:[(0,y.jsx)(a,{namespace:E,phrase:`timezoneCurrent`,options:{timezone:e.timezone}}),` — `,(0,y.jsx)(`button`,{className:`btn btn-link text-info p-0 align-baseline`,onClick:()=>n(!0),children:(0,y.jsx)(a,{namespace:E,phrase:`timezoneChange`})})]})})]})}var A=`reports.classroomViewsPopup`,j=s.encloseNamespace(A);function M(e){let n=h(t.ClassroomViewsPopup),{enableAlert:r}=_(n.hasClassroomViews),i=g(),s=o.timeStringToHour(n.schoolStartTime),l=o.timeStringToHour(n.schoolEndTime),[p,m]=v.useState(n.hasClassroomViews),[b,x]=v.useState(n.classroomSize),[S,w]=v.useState(n.timezone),[E,D]=v.useState(s),[O,M]=v.useState(l),[N,P]=v.useState(!1),F=!p||E<O&&S,I=p!==n.hasClassroomViews||b!==n.classroomSize||S!==n.timezone||E!==s||O!==l;async function L(){try{P(!0),await n.updateSettingsAsync({hasClassroomViews:p,schoolStartTime:o.hourToTimeString(E),schoolEndTime:o.hourToTimeString(O),timezone:S,classroomSize:b}),i.success(j(`success`)),p||r(),e.closePopup()}catch{i.error(j(`error`))}finally{P(!1)}}return(0,y.jsxs)(f,{closePopup:e.closePopup,title:j(`title`),size:`lg`,children:[(0,y.jsx)(`p`,{children:(0,y.jsx)(a,{namespace:A,phrase:`description1`})}),(0,y.jsx)(`p`,{children:(0,y.jsx)(a,{namespace:A,phrase:`description2`})}),(0,y.jsx)(T,{className:`my-3`,enabled:p,onEnabledChanged:m}),p&&(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(C,{className:`mb-3`,classroomSize:b,onClassroomSizeChanged:x}),(0,y.jsx)(k,{className:`mb-3`,startHour:E,endHour:O,timezone:S,onStartHourChanged:D,onEndHourChanged:M,onTimezoneChanged:w})]}),(0,y.jsxs)(d,{className:`justify-content-between`,children:[(0,y.jsx)(`a`,{href:c.getLiteArticle(u.ClassroomViews),target:`_blank`,rel:`noopener noreferrer`,className:`text-info`,children:(0,y.jsx)(a,{namespace:A,phrase:`learnMore`})}),(0,y.jsxs)(`div`,{className:`d-flex`,children:[(0,y.jsx)(d.Cancel,{onClick:e.closePopup,text:j(`close`)}),(0,y.jsx)(d.Submit,{onClick:L,text:j(`save`),showSpinner:N,variant:`dark`,disabled:!F||!I})]})]})]})}export{M as ClassroomViewsPopupView};
2
+ //# sourceMappingURL=DbSzdDBS2.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DzTraroE2.chunk.js","names":[],"sources":["../../src/apps/default/views/classroom-views-popup/components/classroom-size-selector/ClassroomSizeSelector.tsx","../../src/apps/default/views/classroom-views-popup/components/classroom-views-toggle/ClassroomViewsToggle.tsx","../../src/apps/default/views/classroom-views-popup/components/school-hours-selector/SchoolHoursSelector.tsx","../../src/apps/default/views/classroom-views-popup/ClassroomViewsPopupView.tsx"],"sourcesContent":["import React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'reportsDefault.classroomSizeSelector';\n\nconst MIN_CLASSROOM_SIZE = 10;\nconst MAX_CLASSROOM_SIZE = 40;\n\ninterface ClassroomSizeSelectorProps {\n className?: string;\n classroomSize: number;\n onClassroomSizeChanged: (size: number) => void;\n}\n\nexport function ClassroomSizeSelector(props: ClassroomSizeSelectorProps) {\n return (\n <div className={classNames('border rounded-3 p-3', props.className)}>\n <h3 className='h6 fw-semibold mb-1'><Text namespace={namespace} phrase='classroomSizeTitle' /></h3>\n <p className='text-secondary mb-3'><Text namespace={namespace} phrase='classroomSizeDescription' /></p>\n\n <label className='mb-1' htmlFor='classroomSize'><Text namespace={namespace} phrase='classroomSizeLabel' /></label>\n\n <Form.Range\n id='classroomSize'\n min={MIN_CLASSROOM_SIZE}\n max={MAX_CLASSROOM_SIZE}\n step={1}\n value={props.classroomSize}\n onChange={e => props.onClassroomSizeChanged(Number(e.target.value))}\n />\n <div className='d-flex justify-content-between small mb-2'>\n <span>{MIN_CLASSROOM_SIZE}</span>\n <span>{MAX_CLASSROOM_SIZE}</span>\n </div>\n\n <p className='text-secondary mb-0'>\n <Text namespace={namespace} phrase='classroomSizeSummary' options={{ count: props.classroomSize }} />\n </p>\n </div>\n );\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ToggleSwitch } from 'libs/shared/components/toggle-switch/ToggleSwitch';\n\nconst namespace = 'reportsDefault.classroomViewsToggle';\n\ninterface ClassroomViewsToggleProps {\n className?: string;\n enabled: boolean;\n onEnabledChanged: (enabled: boolean) => void;\n}\n\nexport function ClassroomViewsToggle(props: ClassroomViewsToggleProps) {\n return (\n <div className={classNames('border rounded-3 p-3 d-flex align-items-center gap-3', props.className)}>\n <div className='flex-grow-1'>\n <h3 className='h6 fw-semibold mb-1'><Text namespace={namespace} phrase='title' /></h3>\n <p className='text-secondary mb-0'><Text namespace={namespace} phrase='description' /></p>\n </div>\n\n <ToggleSwitch\n on={props.enabled}\n floatEnd={false}\n onClick={() => props.onEnabledChanged(!props.enabled)}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { TimezoneHelper } from 'libs/shared/apps/streamable-learning/utils/TimezoneHelper';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'reportsDefault.schoolHoursSelector';\n\nconst SCHOOL_HOURS = [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 ];\nconst ALL_TIMEZONES = TimezoneHelper.getTimezones();\n\ninterface SchoolHoursSelectorProps {\n className?: string;\n startHour: number;\n endHour: number;\n timezone: string;\n onStartHourChanged: (hour: number) => void;\n onEndHourChanged: (hour: number) => void;\n onTimezoneChanged: (tz: string) => void;\n}\n\nexport function SchoolHoursSelector(props: SchoolHoursSelectorProps) {\n const [ showTimezoneSelect, setShowTimezoneSelect ] = React.useState(false);\n\n const isTimeRangeValid = props.startHour < props.endHour;\n\n return (\n <div className={classNames('border rounded-3 p-3', props.className)}>\n <h3 className='h6 fw-semibold mb-1'><Text namespace={namespace} phrase='schoolHoursTitle' /></h3>\n <p className='text-secondary mb-3'><Text namespace={namespace} phrase='schoolHoursDescription' /></p>\n\n <div className='d-flex align-items-end gap-3 mb-2'>\n <div className='flex-grow-1'>\n <label className='small mb-1 d-block'><Text namespace={namespace} phrase='startTimeLabel' /></label>\n <select\n className='form-select'\n value={props.startHour}\n onChange={e => props.onStartHourChanged(Number(e.target.value))}\n >\n {SCHOOL_HOURS.map(hour => (\n <option key={hour} value={hour}>{DateHelper.hourToFriendlyString(hour)}</option>\n ))}\n </select>\n </div>\n <span className='pb-2'><Text namespace={namespace} phrase='schoolHoursTo' /></span>\n <div className='flex-grow-1'>\n <label className='small mb-1 d-block'><Text namespace={namespace} phrase='endTimeLabel' /></label>\n <select\n className='form-select'\n value={props.endHour}\n onChange={e => props.onEndHourChanged(Number(e.target.value))}\n >\n {SCHOOL_HOURS.map(hour => (\n <option key={hour} value={hour}>{DateHelper.hourToFriendlyString(hour)}</option>\n ))}\n </select>\n </div>\n </div>\n\n {isTimeRangeValid ? (\n <p className='text-secondary mb-0'>\n <Text\n namespace={namespace}\n phrase='schoolHoursSummary'\n options={{\n startTime: DateHelper.hourToFriendlyString(props.startHour),\n endTime: DateHelper.hourToFriendlyString(props.endHour)\n }}\n />\n </p>\n ) : (\n <p className='text-danger mb-0'>\n <Text namespace={namespace} phrase='schoolHoursValidation' />\n </p>\n )}\n\n <div className='mt-3'>\n {showTimezoneSelect ? (\n <>\n <label className='mb-1 d-block'><Text namespace={namespace} phrase='timezoneLabel' /></label>\n <select className='form-select' value={props.timezone} onChange={e => props.onTimezoneChanged(e.target.value)}>\n {ALL_TIMEZONES.map(tz => (\n <option key={tz} value={tz}>{tz}</option>\n ))}\n </select>\n </>\n ) : (\n <span className='text-secondary'>\n <Text namespace={namespace} phrase='timezoneCurrent' options={{ timezone: props.timezone }} />\n {' — '}\n <button className='btn btn-link text-info p-0 align-baseline' onClick={() => setShowTimezoneSelect(true)}>\n <Text namespace={namespace} phrase='timezoneChange' />\n </button>\n </span>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { LiteSupportArticle } from 'libs/shared/enums/SupportArticle';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { PopupViewProps } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nimport { useClassroomViewsAlert } from 'shared/hooks/useClassroomViewsAlert';\nimport { useClassroomViewsSettings } from 'shared/hooks/useClassroomViewsSettings';\n\nimport { ClassroomSizeSelector } from './components/classroom-size-selector/ClassroomSizeSelector';\nimport { ClassroomViewsToggle } from './components/classroom-views-toggle/ClassroomViewsToggle';\nimport { SchoolHoursSelector } from './components/school-hours-selector/SchoolHoursSelector';\n\nconst namespace = 'reports.classroomViewsPopup';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function ClassroomViewsPopupView(props: PopupViewProps): JSX.Element {\n const classroomViewsSettings = useClassroomViewsSettings(LocationContext.ClassroomViewsPopup);\n const { enableAlert } = useClassroomViewsAlert(classroomViewsSettings.hasClassroomViews);\n const alerts = useAlerts();\n\n const initialStartHour = DateHelper.timeStringToHour(classroomViewsSettings.schoolStartTime);\n const initialEndHour = DateHelper.timeStringToHour(classroomViewsSettings.schoolEndTime);\n \n const [ hasClassroomViews, setHasClassroomViews ] = React.useState(classroomViewsSettings.hasClassroomViews);\n const [ classroomSize, setClassroomSize ] = React.useState(classroomViewsSettings.classroomSize);\n const [ timezone, setTimezone ] = React.useState(classroomViewsSettings.timezone);\n const [ schoolStartHour, setSchoolStartHour ] = React.useState(initialStartHour);\n const [ schoolEndHour, setSchoolEndHour ] = React.useState(initialEndHour);\n const [ isSaving, setIsSaving ] = React.useState(false);\n\n const isFormValid = hasClassroomViews ? (schoolStartHour < schoolEndHour && timezone) : true;\n const isDirty = hasClassroomViews !== classroomViewsSettings.hasClassroomViews\n || classroomSize !== classroomViewsSettings.classroomSize\n || timezone !== classroomViewsSettings.timezone\n || schoolStartHour !== initialStartHour\n || schoolEndHour !== initialEndHour;\n\n async function onSave() {\n try {\n setIsSaving(true);\n \n await classroomViewsSettings.updateSettingsAsync({\n hasClassroomViews,\n schoolStartTime: DateHelper.hourToTimeString(schoolStartHour),\n schoolEndTime: DateHelper.hourToTimeString(schoolEndHour),\n timezone,\n classroomSize\n });\n \n alerts.success(getPhrase('success'));\n\n // We re-enable the alert if the user has just turned off Classroom Views, \n // to give them a reminder about the feature and how to turn it back on..\n if (!hasClassroomViews)\n enableAlert();\n \n props.closePopup();\n } catch {\n alerts.error(getPhrase('error'));\n } finally {\n setIsSaving(false);\n }\n }\n\n return (\n <Popup\n closePopup={props.closePopup}\n title={getPhrase('title')}\n size='lg'\n >\n <p><Text namespace={namespace} phrase='description1' /></p>\n <p><Text namespace={namespace} phrase='description2' /></p>\n\n <ClassroomViewsToggle\n className='my-3'\n enabled={hasClassroomViews}\n onEnabledChanged={setHasClassroomViews}\n />\n\n {hasClassroomViews && (\n <>\n <ClassroomSizeSelector\n className='mb-3'\n classroomSize={classroomSize}\n onClassroomSizeChanged={setClassroomSize}\n />\n\n <SchoolHoursSelector\n className='mb-3'\n startHour={schoolStartHour}\n endHour={schoolEndHour}\n timezone={timezone}\n onStartHourChanged={setSchoolStartHour}\n onEndHourChanged={setSchoolEndHour}\n onTimezoneChanged={setTimezone}\n />\n </>\n )}\n\n <PopupButtons className='justify-content-between'>\n <a href={ArticleHelper.getLiteArticle(LiteSupportArticle.ClassroomViews)} target='_blank' rel='noopener noreferrer' className='text-info'>\n <Text namespace={namespace} phrase='learnMore' />\n </a>\n <div className='d-flex'>\n <PopupButtons.Cancel onClick={props.closePopup} text={getPhrase('close')} />\n <PopupButtons.Submit onClick={onSave} text={getPhrase('save')} showSpinner={isSaving} variant='dark' disabled={!isFormValid || !isDirty} />\n </div>\n </PopupButtons>\n </Popup>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DbSzdDBS2.chunk.js","names":[],"sources":["../../src/apps/default/views/classroom-views-popup/components/classroom-size-selector/ClassroomSizeSelector.tsx","../../src/apps/default/views/classroom-views-popup/components/classroom-views-toggle/ClassroomViewsToggle.tsx","../../src/apps/default/views/classroom-views-popup/components/school-hours-selector/SchoolHoursSelector.tsx","../../src/apps/default/views/classroom-views-popup/ClassroomViewsPopupView.tsx"],"sourcesContent":["import React from 'react';\nimport { Form } from 'react-bootstrap';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'reportsDefault.classroomSizeSelector';\n\nconst MIN_CLASSROOM_SIZE = 10;\nconst MAX_CLASSROOM_SIZE = 40;\n\ninterface ClassroomSizeSelectorProps {\n className?: string;\n classroomSize: number;\n onClassroomSizeChanged: (size: number) => void;\n}\n\nexport function ClassroomSizeSelector(props: ClassroomSizeSelectorProps) {\n return (\n <div className={classNames('border rounded-3 p-3', props.className)}>\n <h3 className='h6 fw-semibold mb-1'><Text namespace={namespace} phrase='classroomSizeTitle' /></h3>\n <p className='text-secondary mb-3'><Text namespace={namespace} phrase='classroomSizeDescription' /></p>\n\n <label className='mb-1' htmlFor='classroomSize'><Text namespace={namespace} phrase='classroomSizeLabel' /></label>\n\n <Form.Range\n id='classroomSize'\n min={MIN_CLASSROOM_SIZE}\n max={MAX_CLASSROOM_SIZE}\n step={1}\n value={props.classroomSize}\n onChange={e => props.onClassroomSizeChanged(Number(e.target.value))}\n />\n <div className='d-flex justify-content-between small mb-2'>\n <span>{MIN_CLASSROOM_SIZE}</span>\n <span>{MAX_CLASSROOM_SIZE}</span>\n </div>\n\n <p className='text-secondary mb-0'>\n <Text namespace={namespace} phrase='classroomSizeSummary' options={{ count: props.classroomSize }} />\n </p>\n </div>\n );\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\n\nimport { Text } from 'libs/shared/components/text/Text';\nimport { ToggleSwitch } from 'libs/shared/components/toggle-switch/ToggleSwitch';\n\nconst namespace = 'reportsDefault.classroomViewsToggle';\n\ninterface ClassroomViewsToggleProps {\n className?: string;\n enabled: boolean;\n onEnabledChanged: (enabled: boolean) => void;\n}\n\nexport function ClassroomViewsToggle(props: ClassroomViewsToggleProps) {\n return (\n <div className={classNames('border rounded-3 p-3 d-flex align-items-center gap-3', props.className)}>\n <div className='flex-grow-1'>\n <h3 className='h6 fw-semibold mb-1'><Text namespace={namespace} phrase='title' /></h3>\n <p className='text-secondary mb-0'><Text namespace={namespace} phrase='description' /></p>\n </div>\n\n <ToggleSwitch\n on={props.enabled}\n floatEnd={false}\n onClick={() => props.onEnabledChanged(!props.enabled)}\n />\n </div>\n );\n}\n","import React from 'react';\n\nimport { classNames } from 'libs/common/react/utils/ClassNameHelper';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { TimezoneHelper } from 'libs/shared/apps/streamable-learning/utils/TimezoneHelper';\nimport { Text } from 'libs/shared/components/text/Text';\n\nconst namespace = 'reportsDefault.schoolHoursSelector';\n\nconst SCHOOL_HOURS = [ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 ];\nconst ALL_TIMEZONES = TimezoneHelper.getTimezones();\n\ninterface SchoolHoursSelectorProps {\n className?: string;\n startHour: number;\n endHour: number;\n timezone: string;\n onStartHourChanged: (hour: number) => void;\n onEndHourChanged: (hour: number) => void;\n onTimezoneChanged: (tz: string) => void;\n}\n\nexport function SchoolHoursSelector(props: SchoolHoursSelectorProps) {\n const [ showTimezoneSelect, setShowTimezoneSelect ] = React.useState(false);\n\n const isTimeRangeValid = props.startHour < props.endHour;\n\n return (\n <div className={classNames('border rounded-3 p-3', props.className)}>\n <h3 className='h6 fw-semibold mb-1'><Text namespace={namespace} phrase='schoolHoursTitle' /></h3>\n <p className='text-secondary mb-3'><Text namespace={namespace} phrase='schoolHoursDescription' /></p>\n\n <div className='d-flex align-items-end gap-3 mb-2'>\n <div className='flex-grow-1'>\n <label className='small mb-1 d-block'><Text namespace={namespace} phrase='startTimeLabel' /></label>\n <select\n className='form-select'\n value={props.startHour}\n onChange={e => props.onStartHourChanged(Number(e.target.value))}\n >\n {SCHOOL_HOURS.map(hour => (\n <option key={hour} value={hour}>{DateHelper.hourToFriendlyString(hour)}</option>\n ))}\n </select>\n </div>\n <span className='pb-2'><Text namespace={namespace} phrase='schoolHoursTo' /></span>\n <div className='flex-grow-1'>\n <label className='small mb-1 d-block'><Text namespace={namespace} phrase='endTimeLabel' /></label>\n <select\n className='form-select'\n value={props.endHour}\n onChange={e => props.onEndHourChanged(Number(e.target.value))}\n >\n {SCHOOL_HOURS.map(hour => (\n <option key={hour} value={hour}>{DateHelper.hourToFriendlyString(hour)}</option>\n ))}\n </select>\n </div>\n </div>\n\n {isTimeRangeValid ? (\n <p className='text-secondary mb-0'>\n <Text\n namespace={namespace}\n phrase='schoolHoursSummary'\n options={{\n startTime: DateHelper.hourToFriendlyString(props.startHour),\n endTime: DateHelper.hourToFriendlyString(props.endHour)\n }}\n />\n </p>\n ) : (\n <p className='text-danger mb-0'>\n <Text namespace={namespace} phrase='schoolHoursValidation' />\n </p>\n )}\n\n <div className='mt-3'>\n {showTimezoneSelect ? (\n <>\n <label className='mb-1 d-block'><Text namespace={namespace} phrase='timezoneLabel' /></label>\n <select className='form-select' value={props.timezone} onChange={e => props.onTimezoneChanged(e.target.value)}>\n {ALL_TIMEZONES.map(tz => (\n <option key={tz} value={tz}>{tz}</option>\n ))}\n </select>\n </>\n ) : (\n <span className='text-secondary'>\n <Text namespace={namespace} phrase='timezoneCurrent' options={{ timezone: props.timezone }} />\n {' — '}\n <button className='btn btn-link text-info p-0 align-baseline' onClick={() => setShowTimezoneSelect(true)}>\n <Text namespace={namespace} phrase='timezoneChange' />\n </button>\n </span>\n )}\n </div>\n </div>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { LocationContext } from 'libs/analytics/interfaces';\n\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { Text } from 'libs/shared/components/text/Text';\nimport { LiteSupportArticle } from 'libs/shared/enums/SupportArticle';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { PopupViewProps } from 'libs/shared/interfaces';\nimport { ArticleHelper } from 'libs/shared/utils/ArticleHelper';\n\nimport { useClassroomViewsAlert } from 'shared/hooks/useClassroomViewsAlert';\nimport { useClassroomViewsSettings } from 'shared/hooks/useClassroomViewsSettings';\n\nimport { ClassroomSizeSelector } from './components/classroom-size-selector/ClassroomSizeSelector';\nimport { ClassroomViewsToggle } from './components/classroom-views-toggle/ClassroomViewsToggle';\nimport { SchoolHoursSelector } from './components/school-hours-selector/SchoolHoursSelector';\n\nconst namespace = 'reports.classroomViewsPopup';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function ClassroomViewsPopupView(props: PopupViewProps): JSX.Element {\n const classroomViewsSettings = useClassroomViewsSettings(LocationContext.ClassroomViewsPopup);\n const { enableAlert } = useClassroomViewsAlert(classroomViewsSettings.hasClassroomViews);\n const alerts = useAlerts();\n\n const initialStartHour = DateHelper.timeStringToHour(classroomViewsSettings.schoolStartTime);\n const initialEndHour = DateHelper.timeStringToHour(classroomViewsSettings.schoolEndTime);\n \n const [ hasClassroomViews, setHasClassroomViews ] = React.useState(classroomViewsSettings.hasClassroomViews);\n const [ classroomSize, setClassroomSize ] = React.useState(classroomViewsSettings.classroomSize);\n const [ timezone, setTimezone ] = React.useState(classroomViewsSettings.timezone);\n const [ schoolStartHour, setSchoolStartHour ] = React.useState(initialStartHour);\n const [ schoolEndHour, setSchoolEndHour ] = React.useState(initialEndHour);\n const [ isSaving, setIsSaving ] = React.useState(false);\n\n const isFormValid = hasClassroomViews ? (schoolStartHour < schoolEndHour && timezone) : true;\n const isDirty = hasClassroomViews !== classroomViewsSettings.hasClassroomViews\n || classroomSize !== classroomViewsSettings.classroomSize\n || timezone !== classroomViewsSettings.timezone\n || schoolStartHour !== initialStartHour\n || schoolEndHour !== initialEndHour;\n\n async function onSave() {\n try {\n setIsSaving(true);\n \n await classroomViewsSettings.updateSettingsAsync({\n hasClassroomViews,\n schoolStartTime: DateHelper.hourToTimeString(schoolStartHour),\n schoolEndTime: DateHelper.hourToTimeString(schoolEndHour),\n timezone,\n classroomSize\n });\n \n alerts.success(getPhrase('success'));\n\n // We re-enable the alert if the user has just turned off Classroom Views, \n // to give them a reminder about the feature and how to turn it back on..\n if (!hasClassroomViews)\n enableAlert();\n \n props.closePopup();\n } catch {\n alerts.error(getPhrase('error'));\n } finally {\n setIsSaving(false);\n }\n }\n\n return (\n <Popup\n closePopup={props.closePopup}\n title={getPhrase('title')}\n size='lg'\n >\n <p><Text namespace={namespace} phrase='description1' /></p>\n <p><Text namespace={namespace} phrase='description2' /></p>\n\n <ClassroomViewsToggle\n className='my-3'\n enabled={hasClassroomViews}\n onEnabledChanged={setHasClassroomViews}\n />\n\n {hasClassroomViews && (\n <>\n <ClassroomSizeSelector\n className='mb-3'\n classroomSize={classroomSize}\n onClassroomSizeChanged={setClassroomSize}\n />\n\n <SchoolHoursSelector\n className='mb-3'\n startHour={schoolStartHour}\n endHour={schoolEndHour}\n timezone={timezone}\n onStartHourChanged={setSchoolStartHour}\n onEndHourChanged={setSchoolEndHour}\n onTimezoneChanged={setTimezone}\n />\n </>\n )}\n\n <PopupButtons className='justify-content-between'>\n <a href={ArticleHelper.getLiteArticle(LiteSupportArticle.ClassroomViews)} target='_blank' rel='noopener noreferrer' className='text-info'>\n <Text namespace={namespace} phrase='learnMore' />\n </a>\n <div className='d-flex'>\n <PopupButtons.Cancel onClick={props.closePopup} text={getPhrase('close')} />\n <PopupButtons.Submit onClick={onSave} text={getPhrase('save')} showSpinner={isSaving} variant='dark' disabled={!isFormValid || !isDirty} />\n </div>\n </PopupButtons>\n </Popup>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{Er as e,N as t,at as n,qt as r}from"./CrTgNROp.chunk.js";import{C as i,g as a,m as o,n as s,t as c}from"./Dwe-4MVf.chunk.js";import{t as l}from"./Dsv_eF8a.chunk.js";import{n as u}from"./28VvvkVW.chunk.js";import{t as d}from"./7dV7tXUX.chunk.js";import{t as f}from"./BIVEB8w0.chunk.js";import{Dt as p,Ot as m,Rt as h,Z as g,a as _,at as v,yt as y}from"./app-jxJcaenU.js";import{t as b}from"./B0BRYUl5.chunk.js";n();var x=`shared.verifiedEmailError`,S=class extends y{constructor(e,t,n){super(`VerifiedEmailRequiredError`),this.message=e,this.liteUrl=t,this.hasLite=n}get name(){return`VerifiedEmailRequiredError`}get dialogOptions(){let e=u.safeUrlConcat(this.liteUrl,`settings/account`);return{title:f.getPhrase(x,`heading`),text:this.hasLite?`${this.message} ${f.getPhrase(x,`visitSettings`,{href:e})}`:this.message,buttons:[{text:f.getPhrase(x,`close`),className:`btn btn-dark`,success:!0}]}}},C=()=>{let e=o(o(d.currentUser()).data?.isAuthenticated&&p.userProducts()),t=!e.hasCompleted;return{hasProduct:n=>t||e.hasError||!e.data?.length?!1:e.data.some(e=>e.id===n),products:e,isLoadingProducts:t}};function w(){let e=b(),{hasProduct:t,isLoadingProducts:n}=C(),i=o(h.config());function a(n,a,o){if(!n.responseJSON||n.responseJSON?.type!==`no-email`){e.error(a);return}r.throw(new S(o,i.data.liteUrl,t(m.Primary)))}return{handleGenerateReportError:a,loading:!i.hasCompleted||n}}function T(e){return{dateRange:{start:e.start,end:e.end},offsetInMin:Math.abs(new Date().getTimezoneOffset())}}var E={videoViewsReport(e,t){return{url:`{gateway}/v1/analytics/video-views/reports`,key:`video:views:report`,type:i.POST,data:{...T(e),version:t},invalidationKeys:`export`,normalize:!1}},loginsReport(e,t,n,r){return{url:`{gateway}/v1/analytics/logins/reports`,key:`logins:report`,data:T(e),type:i.POST,normalize:!1,success:t,error:n,always:r}}},D=e({GenerateReportType:()=>N,GenerateReportView:()=>P,getReportFriendlyDate:()=>M}),O=t(),k=`reportsShared.generateReport`,A=f.encloseNamespace(k);function j(e){switch(e){case 0:return`loginsDescription`;case 1:return`videosDescription`;default:return``}}function M(e){let t=l.convertUTCToLocal(e).toString();return l.format(t,`Do MMMM YYYY`)}var N=function(e){return e[e.Logins=0]=`Logins`,e[e.VideoViews=1]=`VideoViews`,e}({});function P(e){let t=_(`video-views`),n=_(`logins`),r=e.type===1?t:n,i=b(),{loading:o,handleGenerateReportError:l}=w(),u=a();function d(){switch(e.type){case 0:return E.loginsReport(n);case 1:return E.videoViewsReport(t,`v3`);default:return null}}function f(){u(d()).then(()=>i.success(A(`success`))).catch(e=>l(e,A(`error`),A(`noEmailError`))).finally(e.closePopup)}return(0,O.jsx)(c.Provider,{value:k,children:(0,O.jsxs)(v,{title:A(`title`),showLoadingSpinner:o,closePopup:e.closePopup,children:[(0,O.jsx)(`p`,{children:(0,O.jsx)(s,{phrase:j(e.type)})}),(0,O.jsx)(`p`,{children:(0,O.jsx)(s,{phrase:`dateRange`,options:{dateFrom:M(r.start),dateTo:M(r.end)}})}),(0,O.jsx)(`p`,{children:(0,O.jsx)(s,{phrase:`emailDescription`})}),(0,O.jsxs)(g,{children:[(0,O.jsx)(g.Cancel,{onClick:e.closePopup}),(0,O.jsx)(g.Submit,{variant:`dark`,onClick:f,text:A(`generateReport`)})]})]})})}export{D as n,N as t};
2
- //# sourceMappingURL=NiiRK9j-2.chunk.js.map
1
+ import{Er as e,N as t,at as n,qt as r}from"./CrTgNROp.chunk.js";import{C as i,g as a,m as o,n as s,t as c}from"./Dwe-4MVf.chunk.js";import{t as l}from"./Dsv_eF8a.chunk.js";import{n as u}from"./28VvvkVW.chunk.js";import{t as d}from"./7dV7tXUX.chunk.js";import{t as f}from"./BIVEB8w0.chunk.js";import{Dt as p,Ot as m,Rt as h,Z as g,a as _,at as v,yt as y}from"./app-B1NVV4PT.js";import{t as b}from"./B0BRYUl5.chunk.js";n();var x=`shared.verifiedEmailError`,S=class extends y{constructor(e,t,n){super(`VerifiedEmailRequiredError`),this.message=e,this.liteUrl=t,this.hasLite=n}get name(){return`VerifiedEmailRequiredError`}get dialogOptions(){let e=u.safeUrlConcat(this.liteUrl,`settings/account`);return{title:f.getPhrase(x,`heading`),text:this.hasLite?`${this.message} ${f.getPhrase(x,`visitSettings`,{href:e})}`:this.message,buttons:[{text:f.getPhrase(x,`close`),className:`btn btn-dark`,success:!0}]}}},C=()=>{let e=o(o(d.currentUser()).data?.isAuthenticated&&p.userProducts()),t=!e.hasCompleted;return{hasProduct:n=>t||e.hasError||!e.data?.length?!1:e.data.some(e=>e.id===n),products:e,isLoadingProducts:t}};function w(){let e=b(),{hasProduct:t,isLoadingProducts:n}=C(),i=o(h.config());function a(n,a,o){if(!n.responseJSON||n.responseJSON?.type!==`no-email`){e.error(a);return}r.throw(new S(o,i.data.liteUrl,t(m.Primary)))}return{handleGenerateReportError:a,loading:!i.hasCompleted||n}}function T(e){return{dateRange:{start:e.start,end:e.end},offsetInMin:Math.abs(new Date().getTimezoneOffset())}}var E={videoViewsReport(e,t){return{url:`{gateway}/v1/analytics/video-views/reports`,key:`video:views:report`,type:i.POST,data:{...T(e),version:t},invalidationKeys:`export`,normalize:!1}},loginsReport(e,t,n,r){return{url:`{gateway}/v1/analytics/logins/reports`,key:`logins:report`,data:T(e),type:i.POST,normalize:!1,success:t,error:n,always:r}}},D=e({GenerateReportType:()=>N,GenerateReportView:()=>P,getReportFriendlyDate:()=>M}),O=t(),k=`reportsShared.generateReport`,A=f.encloseNamespace(k);function j(e){switch(e){case 0:return`loginsDescription`;case 1:return`videosDescription`;default:return``}}function M(e){let t=l.convertUTCToLocal(e).toString();return l.format(t,`Do MMMM YYYY`)}var N=function(e){return e[e.Logins=0]=`Logins`,e[e.VideoViews=1]=`VideoViews`,e}({});function P(e){let t=_(`video-views`),n=_(`logins`),r=e.type===1?t:n,i=b(),{loading:o,handleGenerateReportError:l}=w(),u=a();function d(){switch(e.type){case 0:return E.loginsReport(n);case 1:return E.videoViewsReport(t,`v3`);default:return null}}function f(){u(d()).then(()=>i.success(A(`success`))).catch(e=>l(e,A(`error`),A(`noEmailError`))).finally(e.closePopup)}return(0,O.jsx)(c.Provider,{value:k,children:(0,O.jsxs)(v,{title:A(`title`),showLoadingSpinner:o,closePopup:e.closePopup,children:[(0,O.jsx)(`p`,{children:(0,O.jsx)(s,{phrase:j(e.type)})}),(0,O.jsx)(`p`,{children:(0,O.jsx)(s,{phrase:`dateRange`,options:{dateFrom:M(r.start),dateTo:M(r.end)}})}),(0,O.jsx)(`p`,{children:(0,O.jsx)(s,{phrase:`emailDescription`})}),(0,O.jsxs)(g,{children:[(0,O.jsx)(g.Cancel,{onClick:e.closePopup}),(0,O.jsx)(g.Submit,{variant:`dark`,onClick:f,text:A(`generateReport`)})]})]})})}export{D as n,N as t};
2
+ //# sourceMappingURL=Dj87pb142.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"NiiRK9j-2.chunk.js","names":[],"sources":["../../../../libs/shared/src/errors/general/verified-email/VerifiedEmailRequiredError.ts","../../../../libs/shared/src/hooks/UseProducts.ts","../../../../libs/shared/src/hooks/useVerifiedEmailRequiredErrorHandler.ts","../../src/shared/flight-requests/ReportRequests.ts","../../src/shared/views/generate-report/GenerateReportView.tsx"],"sourcesContent":["import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\n\nimport { DialogError } from 'libs/shared/errors/primitives/DialogError';\nimport { DialogOptions } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.verifiedEmailError';\n\nexport class VerifiedEmailRequiredError extends DialogError {\n public message: string;\n public liteUrl: string;\n public hasLite: boolean;\n\n constructor(message: string, liteUrl: string, hasLite: boolean) {\n super('VerifiedEmailRequiredError');\n\n this.message = message;\n this.liteUrl = liteUrl;\n this.hasLite = hasLite;\n }\n\n // @ts-ignore\n public get name(): string {\n return 'VerifiedEmailRequiredError';\n }\n\n // @ts-ignore\n public get dialogOptions(): DialogOptions {\n const href = UrlHelper.safeUrlConcat(this.liteUrl, 'settings/account');\n\n return {\n title: LanguageService.getPhrase(namespace, 'heading'),\n text: this.hasLite ?\n `${this.message} ${LanguageService.getPhrase(namespace, 'visitSettings', { href })}` :\n this.message,\n buttons: [{\n text: LanguageService.getPhrase(namespace, 'close'),\n className: 'btn btn-dark',\n success: true\n }]\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 { Core } from 'libs/common/backbone/index';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/react/index';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { VerifiedEmailRequiredError } from 'libs/shared/errors/general/verified-email/VerifiedEmailRequiredError';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { Config } from 'libs/shared/interfaces';\n\nexport function useVerifiedEmailRequiredErrorHandler() {\n const alerts = useAlerts();\n const { hasProduct, isLoadingProducts } = useProducts();\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n function handleGenerateReportError(xhr: Xhr, message: string, noEmailError: string) {\n if (!xhr.responseJSON || xhr.responseJSON?.type !== 'no-email') {\n alerts.error(message);\n return;\n }\n\n Core.ErrorHelper.throw(\n new VerifiedEmailRequiredError(noEmailError, config.data.liteUrl, hasProduct(ProductId.Primary))\n );\n }\n\n return {\n handleGenerateReportError,\n loading: !config.hasCompleted || isLoadingProducts\n };\n}\n","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\ntype ReportVersion = 'v2' | 'v3';\n\ninterface DateRange {\n start: string;\n end: string;\n}\n\ninterface ReportRequestPayload {\n dateRange: DateRange;\n offsetInMin: number;\n userIds?: number[];\n groupsIds?: number[];\n}\n\nfunction formatReportRequest(filterParams: AnalyticsRequestFilter): ReportRequestPayload {\n return {\n dateRange: {\n start: filterParams.start,\n end: filterParams.end\n },\n offsetInMin: Math.abs(new Date().getTimezoneOffset())\n };\n}\n\nexport const ReportRequests = {\n videoViewsReport(\n filterParams: AnalyticsRequestFilter,\n version: ReportVersion\n ): Flight.Request {\n return {\n url: '{gateway}/v1/analytics/video-views/reports',\n key: 'video:views:report',\n type: HttpVerbs.POST,\n data: { ...formatReportRequest(filterParams), version },\n invalidationKeys: 'export',\n normalize: false\n };\n },\n\n loginsReport(\n filterParams: AnalyticsRequestFilter,\n success?: () => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: '{gateway}/v1/analytics/logins/reports',\n key: 'logins:report',\n data: formatReportRequest(filterParams),\n type: HttpVerbs.POST,\n normalize: false,\n success,\n error,\n always\n };\n }\n};\n","import React from 'react';\n\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useVerifiedEmailRequiredErrorHandler } from 'libs/shared/hooks/useVerifiedEmailRequiredErrorHandler';\nimport { PropsWithPopupViewProps } from 'libs/shared/interfaces';\n\nimport { ReportRequests } from 'shared/flight-requests/ReportRequests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\n\nconst namespace = 'reportsShared.generateReport';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getLangPhrase(type: GenerateReportType): string {\n switch (type) {\n case GenerateReportType.Logins:\n return 'loginsDescription';\n\n case GenerateReportType.VideoViews:\n return 'videosDescription';\n\n default:\n return '';\n }\n}\n\nexport function getReportFriendlyDate(date: string): string {\n const localDate = DateHelper.convertUTCToLocal(date).toString();\n return DateHelper.format(localDate, 'Do MMMM YYYY');\n}\n\nexport enum GenerateReportType {\n Logins,\n VideoViews\n}\n\ninterface GenerateReportViewProps {\n type: GenerateReportType;\n}\n\nexport function GenerateReportView(props: PropsWithPopupViewProps<GenerateReportViewProps>): JSX.Element {\n const videoViewsFilter = useGetRequestFilter('video-views');\n const loginsFilter = useGetRequestFilter('logins');\n const filterQueryParams = props.type === GenerateReportType.VideoViews ? videoViewsFilter : loginsFilter;\n const alerts = useAlerts();\n const { loading, handleGenerateReportError } = useVerifiedEmailRequiredErrorHandler();\n\n const fetchAsync = Flight.useGetFetchAsync();\n\n function getRequest(): Flight.Request {\n switch (props.type) {\n case GenerateReportType.Logins:\n return ReportRequests.loginsReport(loginsFilter);\n\n case GenerateReportType.VideoViews:\n return ReportRequests.videoViewsReport(videoViewsFilter, 'v3');\n\n default:\n return null;\n }\n }\n\n function onClick() {\n fetchAsync(getRequest())\n .then(() => alerts.success(getPhrase('success')))\n .catch((xhr: Xhr) => handleGenerateReportError(xhr, getPhrase('error'), getPhrase('noEmailError')))\n .finally(props.closePopup);\n }\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <Popup\n title={getPhrase('title')}\n showLoadingSpinner={loading}\n closePopup={props.closePopup}\n >\n <p>\n <Text phrase={getLangPhrase(props.type)} />\n </p>\n <p>\n <Text phrase='dateRange' options={({\n dateFrom: getReportFriendlyDate(filterQueryParams.start),\n dateTo: getReportFriendlyDate(filterQueryParams.end)\n })} />\n </p>\n <p>\n <Text phrase='emailDescription' />\n </p>\n <PopupButtons>\n <PopupButtons.Cancel onClick={props.closePopup} />\n <PopupButtons.Submit\n variant='dark'\n onClick={onClick}\n text={getPhrase('generateReport')}\n />\n </PopupButtons>\n </Popup>\n </LanguageNamespaceContext.Provider>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"Dj87pb142.chunk.js","names":[],"sources":["../../../../libs/shared/src/errors/general/verified-email/VerifiedEmailRequiredError.ts","../../../../libs/shared/src/hooks/UseProducts.ts","../../../../libs/shared/src/hooks/useVerifiedEmailRequiredErrorHandler.ts","../../src/shared/flight-requests/ReportRequests.ts","../../src/shared/views/generate-report/GenerateReportView.tsx"],"sourcesContent":["import { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\n\nimport { DialogError } from 'libs/shared/errors/primitives/DialogError';\nimport { DialogOptions } from 'libs/shared/interfaces';\n\nconst namespace = 'shared.verifiedEmailError';\n\nexport class VerifiedEmailRequiredError extends DialogError {\n public message: string;\n public liteUrl: string;\n public hasLite: boolean;\n\n constructor(message: string, liteUrl: string, hasLite: boolean) {\n super('VerifiedEmailRequiredError');\n\n this.message = message;\n this.liteUrl = liteUrl;\n this.hasLite = hasLite;\n }\n\n // @ts-ignore\n public get name(): string {\n return 'VerifiedEmailRequiredError';\n }\n\n // @ts-ignore\n public get dialogOptions(): DialogOptions {\n const href = UrlHelper.safeUrlConcat(this.liteUrl, 'settings/account');\n\n return {\n title: LanguageService.getPhrase(namespace, 'heading'),\n text: this.hasLite ?\n `${this.message} ${LanguageService.getPhrase(namespace, 'visitSettings', { href })}` :\n this.message,\n buttons: [{\n text: LanguageService.getPhrase(namespace, 'close'),\n className: 'btn btn-dark',\n success: true\n }]\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 { Core } from 'libs/common/backbone/index';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/react/index';\n\nimport { ProductId } from 'libs/shared/enums/ProductId';\nimport { VerifiedEmailRequiredError } from 'libs/shared/errors/general/verified-email/VerifiedEmailRequiredError';\nimport { ConfigRequests } from 'libs/shared/flight-requests/ConfigRequests';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useProducts } from 'libs/shared/hooks/UseProducts';\nimport { Config } from 'libs/shared/interfaces';\n\nexport function useVerifiedEmailRequiredErrorHandler() {\n const alerts = useAlerts();\n const { hasProduct, isLoadingProducts } = useProducts();\n const config = Flight.useBasicFetch<Config>(ConfigRequests.config());\n\n function handleGenerateReportError(xhr: Xhr, message: string, noEmailError: string) {\n if (!xhr.responseJSON || xhr.responseJSON?.type !== 'no-email') {\n alerts.error(message);\n return;\n }\n\n Core.ErrorHelper.throw(\n new VerifiedEmailRequiredError(noEmailError, config.data.liteUrl, hasProduct(ProductId.Primary))\n );\n }\n\n return {\n handleGenerateReportError,\n loading: !config.hasCompleted || isLoadingProducts\n };\n}\n","import { HttpVerbs } from 'libs/common/backbone/enums/HttpVerbs';\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { Flight } from 'libs/common/flight';\n\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\ntype ReportVersion = 'v2' | 'v3';\n\ninterface DateRange {\n start: string;\n end: string;\n}\n\ninterface ReportRequestPayload {\n dateRange: DateRange;\n offsetInMin: number;\n userIds?: number[];\n groupsIds?: number[];\n}\n\nfunction formatReportRequest(filterParams: AnalyticsRequestFilter): ReportRequestPayload {\n return {\n dateRange: {\n start: filterParams.start,\n end: filterParams.end\n },\n offsetInMin: Math.abs(new Date().getTimezoneOffset())\n };\n}\n\nexport const ReportRequests = {\n videoViewsReport(\n filterParams: AnalyticsRequestFilter,\n version: ReportVersion\n ): Flight.Request {\n return {\n url: '{gateway}/v1/analytics/video-views/reports',\n key: 'video:views:report',\n type: HttpVerbs.POST,\n data: { ...formatReportRequest(filterParams), version },\n invalidationKeys: 'export',\n normalize: false\n };\n },\n\n loginsReport(\n filterParams: AnalyticsRequestFilter,\n success?: () => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: '{gateway}/v1/analytics/logins/reports',\n key: 'logins:report',\n data: formatReportRequest(filterParams),\n type: HttpVerbs.POST,\n normalize: false,\n success,\n error,\n always\n };\n }\n};\n","import React from 'react';\n\nimport { Xhr } from 'libs/common/backbone/interfaces';\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/flight';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { Popup } from 'libs/shared/components/popup/Popup';\nimport { PopupButtons } from 'libs/shared/components/popup/PopupButtons';\nimport { LanguageNamespaceContext, Text } from 'libs/shared/components/text/Text';\nimport { useAlerts } from 'libs/shared/hooks/UseAlerts';\nimport { useVerifiedEmailRequiredErrorHandler } from 'libs/shared/hooks/useVerifiedEmailRequiredErrorHandler';\nimport { PropsWithPopupViewProps } from 'libs/shared/interfaces';\n\nimport { ReportRequests } from 'shared/flight-requests/ReportRequests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\n\nconst namespace = 'reportsShared.generateReport';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nfunction getLangPhrase(type: GenerateReportType): string {\n switch (type) {\n case GenerateReportType.Logins:\n return 'loginsDescription';\n\n case GenerateReportType.VideoViews:\n return 'videosDescription';\n\n default:\n return '';\n }\n}\n\nexport function getReportFriendlyDate(date: string): string {\n const localDate = DateHelper.convertUTCToLocal(date).toString();\n return DateHelper.format(localDate, 'Do MMMM YYYY');\n}\n\nexport enum GenerateReportType {\n Logins,\n VideoViews\n}\n\ninterface GenerateReportViewProps {\n type: GenerateReportType;\n}\n\nexport function GenerateReportView(props: PropsWithPopupViewProps<GenerateReportViewProps>): JSX.Element {\n const videoViewsFilter = useGetRequestFilter('video-views');\n const loginsFilter = useGetRequestFilter('logins');\n const filterQueryParams = props.type === GenerateReportType.VideoViews ? videoViewsFilter : loginsFilter;\n const alerts = useAlerts();\n const { loading, handleGenerateReportError } = useVerifiedEmailRequiredErrorHandler();\n\n const fetchAsync = Flight.useGetFetchAsync();\n\n function getRequest(): Flight.Request {\n switch (props.type) {\n case GenerateReportType.Logins:\n return ReportRequests.loginsReport(loginsFilter);\n\n case GenerateReportType.VideoViews:\n return ReportRequests.videoViewsReport(videoViewsFilter, 'v3');\n\n default:\n return null;\n }\n }\n\n function onClick() {\n fetchAsync(getRequest())\n .then(() => alerts.success(getPhrase('success')))\n .catch((xhr: Xhr) => handleGenerateReportError(xhr, getPhrase('error'), getPhrase('noEmailError')))\n .finally(props.closePopup);\n }\n\n return (\n <LanguageNamespaceContext.Provider value={namespace}>\n <Popup\n title={getPhrase('title')}\n showLoadingSpinner={loading}\n closePopup={props.closePopup}\n >\n <p>\n <Text phrase={getLangPhrase(props.type)} />\n </p>\n <p>\n <Text phrase='dateRange' options={({\n dateFrom: getReportFriendlyDate(filterQueryParams.start),\n dateTo: getReportFriendlyDate(filterQueryParams.end)\n })} />\n </p>\n <p>\n <Text phrase='emailDescription' />\n </p>\n <PopupButtons>\n <PopupButtons.Cancel onClick={props.closePopup} />\n <PopupButtons.Submit\n variant='dark'\n onClick={onClick}\n text={getPhrase('generateReport')}\n />\n </PopupButtons>\n </Popup>\n </LanguageNamespaceContext.Provider>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{N as e,at as t}from"./CrTgNROp.chunk.js";import{m as n,n as r}from"./Dwe-4MVf.chunk.js";import{t as i}from"./BIVEB8w0.chunk.js";import{t as a}from"./CPrWMnN-.chunk.js";import{a as o,n as s,r as c,xt as l}from"./app-jxJcaenU.js";import{c as u}from"./CBswLW82.chunk.js";import{n as d,t as f}from"./CsoT7dzm.chunk.js";import{n as p}from"./CkUPoXTo.chunk.js";import{n as m,t as h}from"./DqAzhF3o.chunk.js";import{i as g,n as _}from"./iTyahUCH2.chunk.js";import{t as v}from"./4QdmE5x_2.chunk.js";import{n as y,t as b}from"./CNihWz772.chunk.js";t();var x={image:`_image_1a110_1`},S=e(),C=i.encloseNamespace(`reportsShared.totalViewsByContentCardEmptyState`);function w(){return(0,S.jsxs)(c,{className:`flex-grow-1 justify-content-center`,children:[(0,S.jsx)(c.Image,{src:l.EmptyStates.Shared.PuzzleGroup,className:x.image}),(0,S.jsx)(c.Heading,{className:`h6`,children:C(`heading`)}),(0,S.jsx)(c.Info,{className:`w-100`,children:C(`description`)})]})}var T=`reportsShared.videoViewsByContentCard`,E=i.encloseNamespace(T);function D(){let e=o(`video-views`),t=n(a.aggregation(`content_type`,e));function i(e){switch(e){case`ClickView content`:return u.YELLOW;case`TV content`:return u.PURPLE;case`User generated content`:return u.GREEN}}function s(e){switch(e){case`ClickView content`:return E(`clickview`);case`TV content`:return E(`tv`);case`User generated content`:return E(`userGenerated`)}}function c(e){return e?e.filter(e=>e.name===`ClickView content`||e.name===`TV content`||e.name===`User generated content`).map(e=>({name:s(e.name),y:e.count,color:i(e.name)})):null}let l=c(t.data);return(0,S.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white rounded p-3`,children:l?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`h2`,{className:`h6 mb-3`,children:(0,S.jsx)(r,{namespace:T,phrase:`videoViews`})}),l.length?(0,S.jsx)(y,{data:l}):(0,S.jsx)(w,{})]}):(0,S.jsx)(`div`,{className:`partial-loading-background w-25`,children:`\xA0`})})}var O={column1:`_column1_1s749_1`,column2:`_column2_1s749_4`,videoViewsCard:`_videoViewsCard_1s749_7`},k=i.encloseNamespace(`videos.schoolVideoOverview`),A=50;function j(){return s({title:k(`videos`)}),p(k(`videos`)),g(_()),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(v,{}),(0,S.jsxs)(`div`,{className:`d-flex gap-3`,children:[(0,S.jsxs)(`div`,{className:`d-flex flex-column gap-3 ${O.column1}`,children:[(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(m,{type:`year_group`})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(b,{})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(D,{})})]}),(0,S.jsxs)(`div`,{className:`d-flex flex-column gap-3 ${O.column2}`,children:[(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(h,{type:`user_type`})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(f,{type:d.RootTopic,heading:k(`totalViewsSubject`),emptyStateText:k(`emptySubjects`),limit:A})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(f,{type:d.ChildTopic,heading:k(`totalViewsTopic`),emptyStateText:k(`emptyTopics`),limit:A})})]})]})]})}export{j as SchoolVideoOverviewView};
2
- //# sourceMappingURL=DSNTuwQi2.chunk.js.map
1
+ import{N as e,at as t}from"./CrTgNROp.chunk.js";import{m as n,n as r}from"./Dwe-4MVf.chunk.js";import{t as i}from"./BIVEB8w0.chunk.js";import{t as a}from"./7M6FzdyD.chunk.js";import{a as o,n as s,r as c,xt as l}from"./app-B1NVV4PT.js";import{c as u}from"./Bzx4bLV8.chunk.js";import{n as d,t as f}from"./fh6sbun-.chunk.js";import{n as p}from"./4gz8eG_F.chunk.js";import{n as m,t as h}from"./CitsW6ql.chunk.js";import{i as g,n as _}from"./CowQEpZQ2.chunk.js";import{t as v}from"./CKKR2-wU2.chunk.js";import{n as y,t as b}from"./BU8DxGLM2.chunk.js";t();var x={image:`_image_1a110_1`},S=e(),C=i.encloseNamespace(`reportsShared.totalViewsByContentCardEmptyState`);function w(){return(0,S.jsxs)(c,{className:`flex-grow-1 justify-content-center`,children:[(0,S.jsx)(c.Image,{src:l.EmptyStates.Shared.PuzzleGroup,className:x.image}),(0,S.jsx)(c.Heading,{className:`h6`,children:C(`heading`)}),(0,S.jsx)(c.Info,{className:`w-100`,children:C(`description`)})]})}var T=`reportsShared.videoViewsByContentCard`,E=i.encloseNamespace(T);function D(){let e=o(`video-views`),t=n(a.aggregation(`content_type`,e));function i(e){switch(e){case`ClickView content`:return u.YELLOW;case`TV content`:return u.PURPLE;case`User generated content`:return u.GREEN}}function s(e){switch(e){case`ClickView content`:return E(`clickview`);case`TV content`:return E(`tv`);case`User generated content`:return E(`userGenerated`)}}function c(e){return e?e.filter(e=>e.name===`ClickView content`||e.name===`TV content`||e.name===`User generated content`).map(e=>({name:s(e.name),y:e.count,color:i(e.name)})):null}let l=c(t.data);return(0,S.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white rounded p-3`,children:l?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(`h2`,{className:`h6 mb-3`,children:(0,S.jsx)(r,{namespace:T,phrase:`videoViews`})}),l.length?(0,S.jsx)(y,{data:l}):(0,S.jsx)(w,{})]}):(0,S.jsx)(`div`,{className:`partial-loading-background w-25`,children:`\xA0`})})}var O={column1:`_column1_1s749_1`,column2:`_column2_1s749_4`,videoViewsCard:`_videoViewsCard_1s749_7`},k=i.encloseNamespace(`videos.schoolVideoOverview`),A=50;function j(){return s({title:k(`videos`)}),p(k(`videos`)),g(_()),(0,S.jsxs)(`div`,{children:[(0,S.jsx)(v,{}),(0,S.jsxs)(`div`,{className:`d-flex gap-3`,children:[(0,S.jsxs)(`div`,{className:`d-flex flex-column gap-3 ${O.column1}`,children:[(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(m,{type:`year_group`})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(b,{})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(D,{})})]}),(0,S.jsxs)(`div`,{className:`d-flex flex-column gap-3 ${O.column2}`,children:[(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(h,{type:`user_type`})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(f,{type:d.RootTopic,heading:k(`totalViewsSubject`),emptyStateText:k(`emptySubjects`),limit:A})}),(0,S.jsx)(`div`,{className:O.videoViewsCard,children:(0,S.jsx)(f,{type:d.ChildTopic,heading:k(`totalViewsTopic`),emptyStateText:k(`emptyTopics`),limit:A})})]})]})]})}export{j as SchoolVideoOverviewView};
2
+ //# sourceMappingURL=EvtCZWZL2.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DSNTuwQi2.chunk.js","names":[],"sources":["../../src/shared/views/overview-cards/video-views-by-content-card/empty-state/total-views-by-content-card-empty-state.module.scss","../../src/shared/views/overview-cards/video-views-by-content-card/empty-state/TotalViewsByContentCardEmptyState.tsx","../../src/shared/views/overview-cards/video-views-by-content-card/VideoViewsByContentCard.tsx","../../src/apps/videos/views/school-video-overview/school-video-overview.module.scss","../../src/apps/videos/views/school-video-overview/SchoolVideoOverviewView.tsx"],"sourcesContent":[":local {\n .image {\n width: 12.5rem;\n height: auto;\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';\n\nimport { ImageUrls } from 'shared/constants/ReportsImageUrls';\n\nimport styles from './total-views-by-content-card-empty-state.module.scss';\n\nconst namespace = 'reportsShared.totalViewsByContentCardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function TotalViewsByContentCardEmptyState() {\n return (\n <EmptyState className='flex-grow-1 justify-content-center'>\n <EmptyState.Image\n src={ImageUrls.EmptyStates.Shared.PuzzleGroup}\n className={styles.image}\n />\n <EmptyState.Heading className='h6'>\n {getPhrase('heading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('description')}\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { GroupedAnalyticsCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { ColumnChart } from 'shared/components/column-chart/ColumnChart';\nimport { CHART_COLOUR } from 'shared/constants/ChartStyles';\nimport { VideoViewsV2Requests } from 'shared/flight-requests/VideoViewsV2Requests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { TotalViewsByContentCardEmptyState } from 'shared/views/overview-cards/video-views-by-content-card/empty-state/TotalViewsByContentCardEmptyState';\n\nconst namespace = 'reportsShared.videoViewsByContentCard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nenum ContentType {\n ClickView = 'ClickView content',\n TV = 'TV content',\n UserGenerated = 'User generated content'\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function VideoViewsByContentCardView() {\n const requestFilter = useGetRequestFilter('video-views');\n\n const contentTypeCount = Flight.useBasicFetch<GroupedAnalyticsCount[]>(\n VideoViewsV2Requests.aggregation('content_type', requestFilter)\n );\n\n function mapContentTypeToChartColour(contentType: string) {\n switch (contentType) {\n case ContentType.ClickView: return CHART_COLOUR.YELLOW;\n case ContentType.TV: return CHART_COLOUR.PURPLE;\n case ContentType.UserGenerated: return CHART_COLOUR.GREEN;\n }\n }\n\n function mapContentTypeToLabel(contentType: string) {\n switch (contentType) {\n case ContentType.ClickView: return getPhrase('clickview');\n case ContentType.TV: return getPhrase('tv');\n case ContentType.UserGenerated: return getPhrase('userGenerated');\n }\n }\n\n function getChartData(contentTypeCount: GroupedAnalyticsCount[]) {\n if (!contentTypeCount) return null;\n\n const mappedGroups = contentTypeCount.filter(group => (\n group.name === ContentType.ClickView ||\n group.name === ContentType.TV ||\n group.name === ContentType.UserGenerated\n )).map(group => ({\n name: mapContentTypeToLabel(group.name),\n y: group.count,\n color: mapContentTypeToChartColour(group.name)\n }));\n\n return mappedGroups;\n }\n\n const chartData = getChartData(contentTypeCount.data);\n\n return (\n <div className='d-flex flex-column h-100 bg-white rounded p-3'>\n {chartData ?\n <>\n <h2 className='h6 mb-3'><Text namespace={namespace} phrase='videoViews' /></h2>\n\n {chartData.length ?\n <ColumnChart data={chartData} /> :\n <TotalViewsByContentCardEmptyState />\n }\n </> :\n <div className='partial-loading-background w-25'>&nbsp;</div>\n }\n </div>\n );\n}\n",":local {\n .column1 {\n flex: 3 0;\n }\n \n .column2 {\n flex: 4 0;\n }\n\n .videoViewsCard {\n height: 20rem;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\n\nimport { TopicAnalyticsType } from 'shared/enums/TopicAnalyticsType';\nimport { useSetHeaderActions } from 'shared/hooks/UseSetHeaderActions';\nimport { useSetHeaderTitle } from 'shared/hooks/UseSetHeaderTitle';\nimport { getVideoHeaderActions } from 'shared/utils/HeaderActionUtils';\nimport { StreamsBarChartCardView } from 'shared/views/overview-cards/streams-bar-chart-card/StreamsBarChartCardView';\nimport { StreamsChartCardView } from 'shared/views/overview-cards/streams-chart-card/StreamsChartCardView';\nimport { TopClassificationsCardView } from 'shared/views/overview-cards/top-classifications-card/TopClassificationsCardView';\nimport { VideoViewsByContentCardView } from 'shared/views/overview-cards/video-views-by-content-card/VideoViewsByContentCard';\nimport { VideoViewsByRoleCardView } from 'shared/views/overview-cards/video-views-by-role-card/VideoViewsByRoleCardView';\n\nimport { SchoolVideosNav } from 'apps/videos/components/school-videos-nav/SchoolVideosNav';\n\nimport styles from './school-video-overview.module.scss';\n\nconst namespace = 'videos.schoolVideoOverview';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst TOP_CLASSIFICATIONS_LIMIT = 50;\n\nexport function SchoolVideoOverviewView(): JSX.Element {\n useSetPageMetadata({ title: getPhrase('videos') });\n useSetHeaderTitle(getPhrase('videos'));\n useSetHeaderActions(getVideoHeaderActions());\n\n return (\n <div>\n <SchoolVideosNav />\n <div className='d-flex gap-3'>\n <div className={`d-flex flex-column gap-3 ${styles.column1}`}>\n <div className={styles.videoViewsCard}>\n <StreamsBarChartCardView type='year_group' />\n </div>\n <div className={styles.videoViewsCard}>\n <VideoViewsByRoleCardView />\n </div>\n <div className={styles.videoViewsCard}>\n <VideoViewsByContentCardView />\n </div>\n </div>\n <div className={`d-flex flex-column gap-3 ${styles.column2}`}>\n <div className={styles.videoViewsCard}>\n <StreamsChartCardView type='user_type' />\n </div>\n <div className={styles.videoViewsCard}>\n <TopClassificationsCardView\n type={TopicAnalyticsType.RootTopic}\n heading={getPhrase('totalViewsSubject')}\n emptyStateText={getPhrase('emptySubjects')}\n limit={TOP_CLASSIFICATIONS_LIMIT}\n />\n </div>\n <div className={styles.videoViewsCard}>\n <TopClassificationsCardView\n type={TopicAnalyticsType.ChildTopic}\n heading={getPhrase('totalViewsTopic')}\n emptyStateText={getPhrase('emptyTopics')}\n limit={TOP_CLASSIFICATIONS_LIMIT}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"EvtCZWZL2.chunk.js","names":[],"sources":["../../src/shared/views/overview-cards/video-views-by-content-card/empty-state/total-views-by-content-card-empty-state.module.scss","../../src/shared/views/overview-cards/video-views-by-content-card/empty-state/TotalViewsByContentCardEmptyState.tsx","../../src/shared/views/overview-cards/video-views-by-content-card/VideoViewsByContentCard.tsx","../../src/apps/videos/views/school-video-overview/school-video-overview.module.scss","../../src/apps/videos/views/school-video-overview/SchoolVideoOverviewView.tsx"],"sourcesContent":[":local {\n .image {\n width: 12.5rem;\n height: auto;\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';\n\nimport { ImageUrls } from 'shared/constants/ReportsImageUrls';\n\nimport styles from './total-views-by-content-card-empty-state.module.scss';\n\nconst namespace = 'reportsShared.totalViewsByContentCardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function TotalViewsByContentCardEmptyState() {\n return (\n <EmptyState className='flex-grow-1 justify-content-center'>\n <EmptyState.Image\n src={ImageUrls.EmptyStates.Shared.PuzzleGroup}\n className={styles.image}\n />\n <EmptyState.Heading className='h6'>\n {getPhrase('heading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('description')}\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\nimport { Flight } from 'libs/common/react/index';\n\nimport { GroupedAnalyticsCount } from 'libs/shared/apps/analytics/interfaces/BaseAnalyticsEvent';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { ColumnChart } from 'shared/components/column-chart/ColumnChart';\nimport { CHART_COLOUR } from 'shared/constants/ChartStyles';\nimport { VideoViewsV2Requests } from 'shared/flight-requests/VideoViewsV2Requests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { TotalViewsByContentCardEmptyState } from 'shared/views/overview-cards/video-views-by-content-card/empty-state/TotalViewsByContentCardEmptyState';\n\nconst namespace = 'reportsShared.videoViewsByContentCard';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nenum ContentType {\n ClickView = 'ClickView content',\n TV = 'TV content',\n UserGenerated = 'User generated content'\n}\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function VideoViewsByContentCardView() {\n const requestFilter = useGetRequestFilter('video-views');\n\n const contentTypeCount = Flight.useBasicFetch<GroupedAnalyticsCount[]>(\n VideoViewsV2Requests.aggregation('content_type', requestFilter)\n );\n\n function mapContentTypeToChartColour(contentType: string) {\n switch (contentType) {\n case ContentType.ClickView: return CHART_COLOUR.YELLOW;\n case ContentType.TV: return CHART_COLOUR.PURPLE;\n case ContentType.UserGenerated: return CHART_COLOUR.GREEN;\n }\n }\n\n function mapContentTypeToLabel(contentType: string) {\n switch (contentType) {\n case ContentType.ClickView: return getPhrase('clickview');\n case ContentType.TV: return getPhrase('tv');\n case ContentType.UserGenerated: return getPhrase('userGenerated');\n }\n }\n\n function getChartData(contentTypeCount: GroupedAnalyticsCount[]) {\n if (!contentTypeCount) return null;\n\n const mappedGroups = contentTypeCount.filter(group => (\n group.name === ContentType.ClickView ||\n group.name === ContentType.TV ||\n group.name === ContentType.UserGenerated\n )).map(group => ({\n name: mapContentTypeToLabel(group.name),\n y: group.count,\n color: mapContentTypeToChartColour(group.name)\n }));\n\n return mappedGroups;\n }\n\n const chartData = getChartData(contentTypeCount.data);\n\n return (\n <div className='d-flex flex-column h-100 bg-white rounded p-3'>\n {chartData ?\n <>\n <h2 className='h6 mb-3'><Text namespace={namespace} phrase='videoViews' /></h2>\n\n {chartData.length ?\n <ColumnChart data={chartData} /> :\n <TotalViewsByContentCardEmptyState />\n }\n </> :\n <div className='partial-loading-background w-25'>&nbsp;</div>\n }\n </div>\n );\n}\n",":local {\n .column1 {\n flex: 3 0;\n }\n \n .column2 {\n flex: 4 0;\n }\n\n .videoViewsCard {\n height: 20rem;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\n\nimport { TopicAnalyticsType } from 'shared/enums/TopicAnalyticsType';\nimport { useSetHeaderActions } from 'shared/hooks/UseSetHeaderActions';\nimport { useSetHeaderTitle } from 'shared/hooks/UseSetHeaderTitle';\nimport { getVideoHeaderActions } from 'shared/utils/HeaderActionUtils';\nimport { StreamsBarChartCardView } from 'shared/views/overview-cards/streams-bar-chart-card/StreamsBarChartCardView';\nimport { StreamsChartCardView } from 'shared/views/overview-cards/streams-chart-card/StreamsChartCardView';\nimport { TopClassificationsCardView } from 'shared/views/overview-cards/top-classifications-card/TopClassificationsCardView';\nimport { VideoViewsByContentCardView } from 'shared/views/overview-cards/video-views-by-content-card/VideoViewsByContentCard';\nimport { VideoViewsByRoleCardView } from 'shared/views/overview-cards/video-views-by-role-card/VideoViewsByRoleCardView';\n\nimport { SchoolVideosNav } from 'apps/videos/components/school-videos-nav/SchoolVideosNav';\n\nimport styles from './school-video-overview.module.scss';\n\nconst namespace = 'videos.schoolVideoOverview';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nconst TOP_CLASSIFICATIONS_LIMIT = 50;\n\nexport function SchoolVideoOverviewView(): JSX.Element {\n useSetPageMetadata({ title: getPhrase('videos') });\n useSetHeaderTitle(getPhrase('videos'));\n useSetHeaderActions(getVideoHeaderActions());\n\n return (\n <div>\n <SchoolVideosNav />\n <div className='d-flex gap-3'>\n <div className={`d-flex flex-column gap-3 ${styles.column1}`}>\n <div className={styles.videoViewsCard}>\n <StreamsBarChartCardView type='year_group' />\n </div>\n <div className={styles.videoViewsCard}>\n <VideoViewsByRoleCardView />\n </div>\n <div className={styles.videoViewsCard}>\n <VideoViewsByContentCardView />\n </div>\n </div>\n <div className={`d-flex flex-column gap-3 ${styles.column2}`}>\n <div className={styles.videoViewsCard}>\n <StreamsChartCardView type='user_type' />\n </div>\n <div className={styles.videoViewsCard}>\n <TopClassificationsCardView\n type={TopicAnalyticsType.RootTopic}\n heading={getPhrase('totalViewsSubject')}\n emptyStateText={getPhrase('emptySubjects')}\n limit={TOP_CLASSIFICATIONS_LIMIT}\n />\n </div>\n <div className={styles.videoViewsCard}>\n <TopClassificationsCardView\n type={TopicAnalyticsType.ChildTopic}\n heading={getPhrase('totalViewsTopic')}\n emptyStateText={getPhrase('emptyTopics')}\n limit={TOP_CLASSIFICATIONS_LIMIT}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{N as e,at as t}from"./CrTgNROp.chunk.js";import{m as n,n as r}from"./Dwe-4MVf.chunk.js";import{t as i}from"./o2slFZEB.chunk.js";import{t as a}from"./Dsv_eF8a.chunk.js";import{t as o}from"./2zJwW9wb.chunk.js";import{n as s}from"./28VvvkVW.chunk.js";import{t as c}from"./BIVEB8w0.chunk.js";import{S as l,a as u,n as d,r as f,xt as p}from"./app-jxJcaenU.js";import{a as m,i as h,n as g,s as _,t as v}from"./CBswLW82.chunk.js";import{n as y,t as b}from"./CkUPoXTo.chunk.js";import{i as x,t as S}from"./iTyahUCH2.chunk.js";t();var C=o(),w={logins(e,t,n,r){return{url:s.urlBuilder(`{gateway}/v1/analytics/logins`,{...e,timeOffset:a.getTimezoneOffset()}),key:b(`logins`,e),normalize:!1,success:t,error:n,always:r}}},T=e(),E={image:`_image_zpxv9_1`},D=c.encloseNamespace(`reportsShared.schoolLoginsByGroupCardEmptyState`);function O(){return(0,T.jsxs)(f,{className:`flex-grow-1 justify-content-center`,children:[(0,T.jsx)(f.Image,{src:p.EmptyStates.Shared.School,className:E.image}),(0,T.jsx)(f.Heading,{className:`h6`,children:D(`heading`)}),(0,T.jsx)(f.Info,{className:`w-100`,children:D(`description`)})]})}var k=`logins.schoolLoginsByGroupCard`;function A(){let e=u(`logins`),t=n(w.logins(e)),i=l(),a=e=>e===`Unknown`||e===null?`Staff`:e,o=g(t.data?.yearGroupCount?.map(e=>({name:a(e.name),count:e.count}))),s=o?.reduce((e,t)=>e+t.y,0);return(0,T.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3`,children:o?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`h2`,{className:`h6 mb-1`,children:(0,T.jsx)(r,{namespace:k,phrase:i?`totalLoginsTertiary`:`totalLogins`,options:{logins:s}})}),o.length?(0,T.jsx)(C.Scrollbars,{className:`position-relative`,children:(0,T.jsx)(`div`,{className:`position-absolute w-100`,children:(0,T.jsx)(_,{data:o})})}):(0,T.jsx)(O,{})]}):(0,T.jsx)(`div`,{className:`partial-loading-background w-50`,children:`\xA0`})})}var j={MONTH:35,YEAR:365},M={day:`YYYY-MM-DD`,month:`YYYY-MM`,year:`YYYY`},N={day:`D MMM`,month:`MMM`,year:`YYYY`};function P(e){let t=a.diffBetween(e.end,e.start,`day`);return t>j.YEAR?`year`:t>j.MONTH?`month`:`day`}function F(e,t){let n=[],r=a.convertUTCToLocal(e.start),i=a.convertUTCToLocal(e.end),o=a.format(r,M[t]);for(;!a.isAfter(o,i,t);)n.push(o),o=a.format(a.add(o,1,t),M[t]);return n}function I(e,t){if(!e)return null;let n=P(t),r=F(t,n),o={};e.forEach(e=>{if(!e.userType)return;let t=`groupedDateWatched`in e&&e.groupedDateWatched||`groupedLoggedOn`in e&&e.groupedLoggedOn,r=a.format(a.convertUTCToLocal(t),M[n]);o[e.userType]=o[e.userType]??{},o[e.userType][r]=o[e.userType][r]??0,o[e.userType][r]+=e.count});let s=Object.keys(o);return s.length?{categories:r.map(e=>a.format(e,N[n])),data:i.sortBy(s.map(e=>({name:m(e),type:`line`,data:r.map(t=>o[e][t]??0),color:h(e)})),`name`)}:{categories:r.map(e=>a.format(e,N[n])),data:[]}}var L=`logins.schoolLoginsByMonthCard`;function R(){let e=u(`logins`),t=I(n(w.logins(e)).data?.data,e);return(0,T.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white rounded p-3 position-relative`,children:t?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`h2`,{className:`position-absolute h6 mb-1`,children:(0,T.jsx)(r,{namespace:L,phrase:`loginActivity`})}),(0,T.jsx)(v,{categories:t.categories,data:t.data})]}):(0,T.jsx)(`div`,{className:`partial-loading-background w-25`,children:`\xA0`})})}var z={column2:`_column2_1cfp0_1`,column1:`_column1_1cfp0_1`},B=c.encloseNamespace(`logins.schoolLoginOverview`);function V(){return d({title:B(`title`)}),y(B(`title`)),x(S()),(0,T.jsx)(`div`,{children:(0,T.jsxs)(`div`,{className:`d-flex gap-3`,children:[(0,T.jsx)(`div`,{className:`${z.column1}`,children:(0,T.jsx)(A,{})}),(0,T.jsx)(`div`,{className:`${z.column2}`,children:(0,T.jsx)(R,{})})]})})}export{V as SchoolLoginOverview};
2
- //# sourceMappingURL=Cdbg16A92.chunk.js.map
1
+ import{N as e,at as t}from"./CrTgNROp.chunk.js";import{m as n,n as r}from"./Dwe-4MVf.chunk.js";import{t as i}from"./o2slFZEB.chunk.js";import{t as a}from"./Dsv_eF8a.chunk.js";import{t as o}from"./2zJwW9wb.chunk.js";import{n as s}from"./28VvvkVW.chunk.js";import{t as c}from"./BIVEB8w0.chunk.js";import{S as l,a as u,n as d,r as f,xt as p}from"./app-B1NVV4PT.js";import{a as m,i as h,n as g,s as _,t as v}from"./Bzx4bLV8.chunk.js";import{n as y,t as b}from"./4gz8eG_F.chunk.js";import{i as x,t as S}from"./CowQEpZQ2.chunk.js";t();var C=o(),w={logins(e,t,n,r){return{url:s.urlBuilder(`{gateway}/v1/analytics/logins`,{...e,timeOffset:a.getTimezoneOffset()}),key:b(`logins`,e),normalize:!1,success:t,error:n,always:r}}},T=e(),E={image:`_image_zpxv9_1`},D=c.encloseNamespace(`reportsShared.schoolLoginsByGroupCardEmptyState`);function O(){return(0,T.jsxs)(f,{className:`flex-grow-1 justify-content-center`,children:[(0,T.jsx)(f.Image,{src:p.EmptyStates.Shared.School,className:E.image}),(0,T.jsx)(f.Heading,{className:`h6`,children:D(`heading`)}),(0,T.jsx)(f.Info,{className:`w-100`,children:D(`description`)})]})}var k=`logins.schoolLoginsByGroupCard`;function A(){let e=u(`logins`),t=n(w.logins(e)),i=l(),a=e=>e===`Unknown`||e===null?`Staff`:e,o=g(t.data?.yearGroupCount?.map(e=>({name:a(e.name),count:e.count}))),s=o?.reduce((e,t)=>e+t.y,0);return(0,T.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3`,children:o?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`h2`,{className:`h6 mb-1`,children:(0,T.jsx)(r,{namespace:k,phrase:i?`totalLoginsTertiary`:`totalLogins`,options:{logins:s}})}),o.length?(0,T.jsx)(C.Scrollbars,{className:`position-relative`,children:(0,T.jsx)(`div`,{className:`position-absolute w-100`,children:(0,T.jsx)(_,{data:o})})}):(0,T.jsx)(O,{})]}):(0,T.jsx)(`div`,{className:`partial-loading-background w-50`,children:`\xA0`})})}var j={MONTH:35,YEAR:365},M={day:`YYYY-MM-DD`,month:`YYYY-MM`,year:`YYYY`},N={day:`D MMM`,month:`MMM`,year:`YYYY`};function P(e){let t=a.diffBetween(e.end,e.start,`day`);return t>j.YEAR?`year`:t>j.MONTH?`month`:`day`}function F(e,t){let n=[],r=a.convertUTCToLocal(e.start),i=a.convertUTCToLocal(e.end),o=a.format(r,M[t]);for(;!a.isAfter(o,i,t);)n.push(o),o=a.format(a.add(o,1,t),M[t]);return n}function I(e,t){if(!e)return null;let n=P(t),r=F(t,n),o={};e.forEach(e=>{if(!e.userType)return;let t=`groupedDateWatched`in e&&e.groupedDateWatched||`groupedLoggedOn`in e&&e.groupedLoggedOn,r=a.format(a.convertUTCToLocal(t),M[n]);o[e.userType]=o[e.userType]??{},o[e.userType][r]=o[e.userType][r]??0,o[e.userType][r]+=e.count});let s=Object.keys(o);return s.length?{categories:r.map(e=>a.format(e,N[n])),data:i.sortBy(s.map(e=>({name:m(e),type:`line`,data:r.map(t=>o[e][t]??0),color:h(e)})),`name`)}:{categories:r.map(e=>a.format(e,N[n])),data:[]}}var L=`logins.schoolLoginsByMonthCard`;function R(){let e=u(`logins`),t=I(n(w.logins(e)).data?.data,e);return(0,T.jsx)(`div`,{className:`d-flex flex-column h-100 bg-white rounded p-3 position-relative`,children:t?(0,T.jsxs)(T.Fragment,{children:[(0,T.jsx)(`h2`,{className:`position-absolute h6 mb-1`,children:(0,T.jsx)(r,{namespace:L,phrase:`loginActivity`})}),(0,T.jsx)(v,{categories:t.categories,data:t.data})]}):(0,T.jsx)(`div`,{className:`partial-loading-background w-25`,children:`\xA0`})})}var z={column2:`_column2_1cfp0_1`,column1:`_column1_1cfp0_1`},B=c.encloseNamespace(`logins.schoolLoginOverview`);function V(){return d({title:B(`title`)}),y(B(`title`)),x(S()),(0,T.jsx)(`div`,{children:(0,T.jsxs)(`div`,{className:`d-flex gap-3`,children:[(0,T.jsx)(`div`,{className:`${z.column1}`,children:(0,T.jsx)(A,{})}),(0,T.jsx)(`div`,{className:`${z.column2}`,children:(0,T.jsx)(R,{})})]})})}export{V as SchoolLoginOverview};
2
+ //# sourceMappingURL=PSwC3iEf2.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Cdbg16A92.chunk.js","names":[],"sources":["../../src/shared/flight-requests/LoginRequests.ts","../../src/apps/logins/views/cards/school-logins-by-group-card/empty-state/school-logins-by-group-card-card-empty-state.module.scss","../../src/apps/logins/views/cards/school-logins-by-group-card/empty-state/SchoolLoginsByGroupCardEmptyState.tsx","../../src/apps/logins/views/cards/school-logins-by-group-card/SchoolLoginsByGroupCardView.tsx","../../src/shared/utils/LineChartByMonthUtils.ts","../../src/apps/logins/views/cards/school-logins-by-month-card/SchoolLoginsByMonthCardView.tsx","../../src/apps/logins/views/school-login-overview/school-login-overview.module.scss","../../src/apps/logins/views/school-login-overview/SchoolLoginOverview.tsx"],"sourcesContent":["import { Xhr } from 'libs/common/backbone/interfaces/Xhr';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { LoginEventResponse } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\nexport const LoginRequests = {\n logins(\n filter: AnalyticsRequestFilter,\n success?: (data: LoginEventResponse) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/logins', {\n ...filter,\n timeOffset: DateHelper.getTimezoneOffset()\n }),\n key: getAnalyticsRequestKey('logins', filter),\n normalize: false,\n success,\n error,\n always\n };\n }\n};\n",":local {\n .image {\n width: 200px;\n height: auto;\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';\n\nimport { ImageUrls } from 'shared/constants/ReportsImageUrls';\n\nconst namespace = 'reportsShared.schoolLoginsByGroupCardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nimport styles from './school-logins-by-group-card-card-empty-state.module.scss';\n\nexport function SchoolLoginsByGroupCardEmptyState() {\n return (\n <EmptyState className='flex-grow-1 justify-content-center'>\n <EmptyState.Image\n src={ImageUrls.EmptyStates.Shared.School}\n className={styles.image}\n />\n <EmptyState.Heading className='h6'>\n {getPhrase('heading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('description')}\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { Flight } from 'libs/common/react/index';\n\nimport { LoginEventResponse } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { VerticalBarChart } from 'shared/components/vertical-bar-chart/VerticalBarChart';\nimport { LoginRequests } from 'shared/flight-requests/LoginRequests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { useIsTertiary } from 'shared/hooks/useIsTertiary';\nimport { getCountByGroup } from 'shared/utils/BarChartByGroupUtils';\n\nimport { SchoolLoginsByGroupCardEmptyState } from './empty-state/SchoolLoginsByGroupCardEmptyState';\n\nconst namespace = 'logins.schoolLoginsByGroupCard';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function SchoolLoginsByGroupCardView() {\n const requestFilter = useGetRequestFilter('logins');\n\n const logins = Flight.useBasicFetch<LoginEventResponse>(LoginRequests.logins(requestFilter));\n \n const isTertiary = useIsTertiary();\n\n const mapNameToGroup = (name: string) => (name === 'Unknown' || name === null) ? 'Staff' : name;\n const totalLoginsByGroupData = getCountByGroup(\n logins.data?.yearGroupCount?.map(group => ({\n name: mapNameToGroup(group.name),\n count: group.count\n }))\n );\n const totalLoginsCount = totalLoginsByGroupData?.reduce((acc, group) => (acc + group.y), 0);\n\n return (\n <div className='d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3'>\n {totalLoginsByGroupData ?\n <>\n <h2 className='h6 mb-1'>\n <Text\n namespace={namespace}\n phrase={isTertiary ? 'totalLoginsTertiary' : 'totalLogins'}\n options={{ logins: totalLoginsCount }}\n />\n </h2>\n\n {totalLoginsByGroupData.length ?\n <Scrollbars className='position-relative'>\n <div className='position-absolute w-100'>\n <VerticalBarChart data={totalLoginsByGroupData} />\n </div>\n </Scrollbars> :\n <SchoolLoginsByGroupCardEmptyState />\n }\n </> :\n <div className='partial-loading-background w-50'>&nbsp;</div>\n }\n </div>\n );\n}\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { LoginEvent } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { VideoViewEvent } from 'libs/shared/apps/analytics/interfaces/VideoViewEvent';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nimport { mapUserTypeToChartColour, mapUserTypeToChartLabel } from 'shared/utils/UserUtils';\n\nconst GroupByThresholds = {\n MONTH: 35,\n YEAR: 365\n};\n\nconst DateFormats = {\n day: 'YYYY-MM-DD',\n month: 'YYYY-MM',\n year: 'YYYY'\n};\n\nconst DisplayFormats = {\n day: 'D MMM',\n month: 'MMM',\n year: 'YYYY'\n};\n\ntype GroupedViewData = {\n [key in UserGroup]?: {\n [date: string]: number\n }\n};\n\ntype GroupBy = 'day' | 'month' | 'year';\n\ninterface ChartData {\n categories: string[];\n data: Highcharts.SeriesLineOptions[];\n}\n\nfunction getGroupBy(requestFilter: AnalyticsRequestFilter): GroupBy {\n const range = DateHelper.diffBetween(requestFilter.end, requestFilter.start, 'day');\n\n if (range > GroupByThresholds.YEAR)\n return 'year';\n\n if (range > GroupByThresholds.MONTH)\n return 'month';\n\n return 'day';\n}\n\nfunction getFullDateRange(requestFilter: AnalyticsRequestFilter, groupBy: GroupBy): string[] {\n const range: string[] = [];\n\n const localStart = DateHelper.convertUTCToLocal(requestFilter.start);\n const localEnd = DateHelper.convertUTCToLocal(requestFilter.end);\n\n let currentDate = DateHelper.format(localStart, DateFormats[groupBy]);\n\n while (!DateHelper.isAfter(currentDate, localEnd, groupBy)) {\n range.push(currentDate);\n currentDate = DateHelper.format(DateHelper.add(currentDate, 1, groupBy), DateFormats[groupBy]);\n }\n\n return range;\n}\n\nexport function getChartData(\n events: VideoViewEvent[] | LoginEvent[],\n requestFilter: AnalyticsRequestFilter\n): ChartData {\n if (!events) return null;\n\n const groupBy = getGroupBy(requestFilter);\n const fullDateRange = getFullDateRange(requestFilter, groupBy);\n \n const grouped: GroupedViewData = {};\n\n events.forEach(ev => {\n if (!ev.userType)\n return;\n\n const eventDate = 'groupedDateWatched' in ev && ev.groupedDateWatched || 'groupedLoggedOn' in ev && ev.groupedLoggedOn;\n const eventDateFormatted = DateHelper.format(DateHelper.convertUTCToLocal(eventDate), DateFormats[groupBy]);\n\n grouped[ev.userType] = grouped[ev.userType] ?? {};\n grouped[ev.userType][eventDateFormatted] = grouped[ev.userType][eventDateFormatted] ?? 0;\n grouped[ev.userType][eventDateFormatted] += ev.count;\n });\n\n const roles = Object.keys(grouped) as UserGroup[];\n\n if (!roles.length) return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data: []\n };\n\n return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data:\n ArrayHelper.sortBy(roles.map(r => ({\n name: mapUserTypeToChartLabel(r),\n type: 'line',\n data: fullDateRange.map(d => grouped[r][d] ?? 0),\n color: mapUserTypeToChartColour(r)\n })), 'name')\n };\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\n\nimport { LoginEventResponse } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { LineChart } from 'shared/components/line-chart/LineChart';\nimport { LoginRequests } from 'shared/flight-requests/LoginRequests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { getChartData } from 'shared/utils/LineChartByMonthUtils';\n\nconst namespace = 'logins.schoolLoginsByMonthCard';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function SchoolLoginsByMonthCardView() {\n const requestFilter = useGetRequestFilter('logins');\n\n const logins = Flight.useBasicFetch<LoginEventResponse>(LoginRequests.logins(requestFilter));\n\n const chartData = getChartData(logins.data?.data, requestFilter);\n\n return (\n <div className='d-flex flex-column h-100 bg-white rounded p-3 position-relative'>\n {chartData ?\n <>\n <h2 className='position-absolute h6 mb-1'><Text namespace={namespace} phrase='loginActivity' /></h2>\n\n <LineChart categories={chartData.categories} data={chartData.data} />\n </> :\n <div className='partial-loading-background w-25'>&nbsp;</div>}\n </div>\n );\n}\n",":local {\n %column {\n height: 30rem;\n }\n\n .column1 {\n @extend %column;\n flex: 3 0;\n }\n \n .column2 {\n @extend %column;\n flex: 4 0;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\n\nimport { useSetHeaderActions } from 'shared/hooks/UseSetHeaderActions';\nimport { useSetHeaderTitle } from 'shared/hooks/UseSetHeaderTitle';\nimport { getLoginHeaderActions } from 'shared/utils/HeaderActionUtils';\n\nimport { SchoolLoginsByGroupCardView } from 'apps/logins/views/cards/school-logins-by-group-card/SchoolLoginsByGroupCardView';\nimport { SchoolLoginsByMonthCardView } from 'apps/logins/views/cards/school-logins-by-month-card/SchoolLoginsByMonthCardView';\n\nimport styles from './school-login-overview.module.scss';\n\nconst namespace = 'logins.schoolLoginOverview';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function SchoolLoginOverview() {\n useSetPageMetadata({ title: getPhrase('title') });\n useSetHeaderTitle(getPhrase('title'));\n useSetHeaderActions(getLoginHeaderActions());\n\n return (\n <div>\n <div className='d-flex gap-3'>\n <div className={`${styles.column1}`}>\n <SchoolLoginsByGroupCardView />\n </div>\n <div className={`${styles.column2}`}>\n <SchoolLoginsByMonthCardView />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"PSwC3iEf2.chunk.js","names":[],"sources":["../../src/shared/flight-requests/LoginRequests.ts","../../src/apps/logins/views/cards/school-logins-by-group-card/empty-state/school-logins-by-group-card-card-empty-state.module.scss","../../src/apps/logins/views/cards/school-logins-by-group-card/empty-state/SchoolLoginsByGroupCardEmptyState.tsx","../../src/apps/logins/views/cards/school-logins-by-group-card/SchoolLoginsByGroupCardView.tsx","../../src/shared/utils/LineChartByMonthUtils.ts","../../src/apps/logins/views/cards/school-logins-by-month-card/SchoolLoginsByMonthCardView.tsx","../../src/apps/logins/views/school-login-overview/school-login-overview.module.scss","../../src/apps/logins/views/school-login-overview/SchoolLoginOverview.tsx"],"sourcesContent":["import { Xhr } from 'libs/common/backbone/interfaces/Xhr';\nimport { UrlHelper } from 'libs/common/backbone/utils/UrlHelper';\nimport { Flight } from 'libs/common/flight';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { LoginEventResponse } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\nimport { getAnalyticsRequestKey } from 'libs/shared/utils/AnalyticsRequestUtils';\n\nexport const LoginRequests = {\n logins(\n filter: AnalyticsRequestFilter,\n success?: (data: LoginEventResponse) => void,\n error?: (xhr: Xhr) => void,\n always?: () => void\n ): Flight.Request {\n return {\n url: UrlHelper.urlBuilder('{gateway}/v1/analytics/logins', {\n ...filter,\n timeOffset: DateHelper.getTimezoneOffset()\n }),\n key: getAnalyticsRequestKey('logins', filter),\n normalize: false,\n success,\n error,\n always\n };\n }\n};\n",":local {\n .image {\n width: 200px;\n height: auto;\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';\n\nimport { ImageUrls } from 'shared/constants/ReportsImageUrls';\n\nconst namespace = 'reportsShared.schoolLoginsByGroupCardEmptyState';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nimport styles from './school-logins-by-group-card-card-empty-state.module.scss';\n\nexport function SchoolLoginsByGroupCardEmptyState() {\n return (\n <EmptyState className='flex-grow-1 justify-content-center'>\n <EmptyState.Image\n src={ImageUrls.EmptyStates.Shared.School}\n className={styles.image}\n />\n <EmptyState.Heading className='h6'>\n {getPhrase('heading')}\n </EmptyState.Heading>\n <EmptyState.Info className='w-100'>\n {getPhrase('description')}\n </EmptyState.Info>\n </EmptyState>\n );\n}\n","import React from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\n\nimport { Flight } from 'libs/common/react/index';\n\nimport { LoginEventResponse } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { VerticalBarChart } from 'shared/components/vertical-bar-chart/VerticalBarChart';\nimport { LoginRequests } from 'shared/flight-requests/LoginRequests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { useIsTertiary } from 'shared/hooks/useIsTertiary';\nimport { getCountByGroup } from 'shared/utils/BarChartByGroupUtils';\n\nimport { SchoolLoginsByGroupCardEmptyState } from './empty-state/SchoolLoginsByGroupCardEmptyState';\n\nconst namespace = 'logins.schoolLoginsByGroupCard';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function SchoolLoginsByGroupCardView() {\n const requestFilter = useGetRequestFilter('logins');\n\n const logins = Flight.useBasicFetch<LoginEventResponse>(LoginRequests.logins(requestFilter));\n \n const isTertiary = useIsTertiary();\n\n const mapNameToGroup = (name: string) => (name === 'Unknown' || name === null) ? 'Staff' : name;\n const totalLoginsByGroupData = getCountByGroup(\n logins.data?.yearGroupCount?.map(group => ({\n name: mapNameToGroup(group.name),\n count: group.count\n }))\n );\n const totalLoginsCount = totalLoginsByGroupData?.reduce((acc, group) => (acc + group.y), 0);\n\n return (\n <div className='d-flex flex-column h-100 bg-white overflow-hidden rounded pt-3 px-3'>\n {totalLoginsByGroupData ?\n <>\n <h2 className='h6 mb-1'>\n <Text\n namespace={namespace}\n phrase={isTertiary ? 'totalLoginsTertiary' : 'totalLogins'}\n options={{ logins: totalLoginsCount }}\n />\n </h2>\n\n {totalLoginsByGroupData.length ?\n <Scrollbars className='position-relative'>\n <div className='position-absolute w-100'>\n <VerticalBarChart data={totalLoginsByGroupData} />\n </div>\n </Scrollbars> :\n <SchoolLoginsByGroupCardEmptyState />\n }\n </> :\n <div className='partial-loading-background w-50'>&nbsp;</div>\n }\n </div>\n );\n}\n","import { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\nimport { DateHelper } from 'libs/common/react/utils/DateHelper';\n\nimport { LoginEvent } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { VideoViewEvent } from 'libs/shared/apps/analytics/interfaces/VideoViewEvent';\nimport { UserGroup } from 'libs/shared/enums/UserGroup';\nimport { AnalyticsRequestFilter } from 'libs/shared/interfaces';\n\nimport { mapUserTypeToChartColour, mapUserTypeToChartLabel } from 'shared/utils/UserUtils';\n\nconst GroupByThresholds = {\n MONTH: 35,\n YEAR: 365\n};\n\nconst DateFormats = {\n day: 'YYYY-MM-DD',\n month: 'YYYY-MM',\n year: 'YYYY'\n};\n\nconst DisplayFormats = {\n day: 'D MMM',\n month: 'MMM',\n year: 'YYYY'\n};\n\ntype GroupedViewData = {\n [key in UserGroup]?: {\n [date: string]: number\n }\n};\n\ntype GroupBy = 'day' | 'month' | 'year';\n\ninterface ChartData {\n categories: string[];\n data: Highcharts.SeriesLineOptions[];\n}\n\nfunction getGroupBy(requestFilter: AnalyticsRequestFilter): GroupBy {\n const range = DateHelper.diffBetween(requestFilter.end, requestFilter.start, 'day');\n\n if (range > GroupByThresholds.YEAR)\n return 'year';\n\n if (range > GroupByThresholds.MONTH)\n return 'month';\n\n return 'day';\n}\n\nfunction getFullDateRange(requestFilter: AnalyticsRequestFilter, groupBy: GroupBy): string[] {\n const range: string[] = [];\n\n const localStart = DateHelper.convertUTCToLocal(requestFilter.start);\n const localEnd = DateHelper.convertUTCToLocal(requestFilter.end);\n\n let currentDate = DateHelper.format(localStart, DateFormats[groupBy]);\n\n while (!DateHelper.isAfter(currentDate, localEnd, groupBy)) {\n range.push(currentDate);\n currentDate = DateHelper.format(DateHelper.add(currentDate, 1, groupBy), DateFormats[groupBy]);\n }\n\n return range;\n}\n\nexport function getChartData(\n events: VideoViewEvent[] | LoginEvent[],\n requestFilter: AnalyticsRequestFilter\n): ChartData {\n if (!events) return null;\n\n const groupBy = getGroupBy(requestFilter);\n const fullDateRange = getFullDateRange(requestFilter, groupBy);\n \n const grouped: GroupedViewData = {};\n\n events.forEach(ev => {\n if (!ev.userType)\n return;\n\n const eventDate = 'groupedDateWatched' in ev && ev.groupedDateWatched || 'groupedLoggedOn' in ev && ev.groupedLoggedOn;\n const eventDateFormatted = DateHelper.format(DateHelper.convertUTCToLocal(eventDate), DateFormats[groupBy]);\n\n grouped[ev.userType] = grouped[ev.userType] ?? {};\n grouped[ev.userType][eventDateFormatted] = grouped[ev.userType][eventDateFormatted] ?? 0;\n grouped[ev.userType][eventDateFormatted] += ev.count;\n });\n\n const roles = Object.keys(grouped) as UserGroup[];\n\n if (!roles.length) return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data: []\n };\n\n return {\n categories: fullDateRange.map(d => DateHelper.format(d, DisplayFormats[groupBy])),\n data:\n ArrayHelper.sortBy(roles.map(r => ({\n name: mapUserTypeToChartLabel(r),\n type: 'line',\n data: fullDateRange.map(d => grouped[r][d] ?? 0),\n color: mapUserTypeToChartColour(r)\n })), 'name')\n };\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/react/index';\n\nimport { LoginEventResponse } from 'libs/shared/apps/analytics/interfaces/LoginEvent';\nimport { Text } from 'libs/shared/components/text/Text';\n\nimport { LineChart } from 'shared/components/line-chart/LineChart';\nimport { LoginRequests } from 'shared/flight-requests/LoginRequests';\nimport { useGetRequestFilter } from 'shared/hooks/UseGetFilterQueryParams';\nimport { getChartData } from 'shared/utils/LineChartByMonthUtils';\n\nconst namespace = 'logins.schoolLoginsByMonthCard';\n\n// eslint-disable-next-line rulesdir/require-view-title\nexport function SchoolLoginsByMonthCardView() {\n const requestFilter = useGetRequestFilter('logins');\n\n const logins = Flight.useBasicFetch<LoginEventResponse>(LoginRequests.logins(requestFilter));\n\n const chartData = getChartData(logins.data?.data, requestFilter);\n\n return (\n <div className='d-flex flex-column h-100 bg-white rounded p-3 position-relative'>\n {chartData ?\n <>\n <h2 className='position-absolute h6 mb-1'><Text namespace={namespace} phrase='loginActivity' /></h2>\n\n <LineChart categories={chartData.categories} data={chartData.data} />\n </> :\n <div className='partial-loading-background w-25'>&nbsp;</div>}\n </div>\n );\n}\n",":local {\n %column {\n height: 30rem;\n }\n\n .column1 {\n @extend %column;\n flex: 3 0;\n }\n \n .column2 {\n @extend %column;\n flex: 4 0;\n }\n}","import React from 'react';\n\nimport { LanguageService } from 'libs/common/backbone/services/LanguageService';\n\nimport { useSetPageMetadata } from 'libs/shared/hooks/useSetPageMetadata';\n\nimport { useSetHeaderActions } from 'shared/hooks/UseSetHeaderActions';\nimport { useSetHeaderTitle } from 'shared/hooks/UseSetHeaderTitle';\nimport { getLoginHeaderActions } from 'shared/utils/HeaderActionUtils';\n\nimport { SchoolLoginsByGroupCardView } from 'apps/logins/views/cards/school-logins-by-group-card/SchoolLoginsByGroupCardView';\nimport { SchoolLoginsByMonthCardView } from 'apps/logins/views/cards/school-logins-by-month-card/SchoolLoginsByMonthCardView';\n\nimport styles from './school-login-overview.module.scss';\n\nconst namespace = 'logins.schoolLoginOverview';\nconst getPhrase = LanguageService.encloseNamespace(namespace);\n\nexport function SchoolLoginOverview() {\n useSetPageMetadata({ title: getPhrase('title') });\n useSetHeaderTitle(getPhrase('title'));\n useSetHeaderActions(getLoginHeaderActions());\n\n return (\n <div>\n <div className='d-flex gap-3'>\n <div className={`${styles.column1}`}>\n <SchoolLoginsByGroupCardView />\n </div>\n <div className={`${styles.column2}`}>\n <SchoolLoginsByMonthCardView />\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{Dr as e,N as t,at as n,it as r}from"./CrTgNROp.chunk.js";import{h as i}from"./Dwe-4MVf.chunk.js";import{t as a}from"./o2slFZEB.chunk.js";import"./HeoWyBUD.chunk.js";import"./app-jxJcaenU.js";var o=e(n()),s=e(r()),c=(function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},e(t,n)};return function(t,n){e(t,n);function r(){this.constructor=t}t.prototype=n===null?Object.create(n):(r.prototype=n.prototype,new r)}})(),l=`html`,u=`svg`,d=`http://www.w3.org/2000/svg`,f=function(e,t){if(t===l)return e instanceof HTMLElement;if(t===u)return e instanceof SVGElement;throw Error(`Unrecognized element type "`+t+`" for validateElementType.`)},p=function(e,t){var n={},r,i,a;if(e===l)a=document.createElement(`div`);else if(e===u)a=document.createElementNS(d,`g`);else throw Error(`Invalid element type "`+e+`" for createPortalNode: must be "html" or "svg".`);if(t&&typeof t==`object`)for(var o=0,s=Object.entries(t.attributes);o<s.length;o++){var c=s[o],p=c[0],m=c[1];a.setAttribute(p,m)}var h={element:a,elementType:e,setPortalProps:function(e){n=e},getInitialPortalProps:function(){return n},mount:function(t,n){if(n!==i){if(h.unmount(),t!==r&&!f(t,e))throw Error(`Invalid element type for portal: "`+e+`" portalNodes must be used with `+e+` elements, but OutPortal is within <`+t.tagName+`>.`);t.replaceChild(h.element,n),r=t,i=n}},unmount:function(e){e&&e!==i||r&&i&&(r.replaceChild(i,h.element),r=void 0,i=void 0)}};return h},m=function(e){c(t,e);function t(t){var n=e.call(this,t)||this;return n.addPropsChannel=function(){Object.assign(n.props.node,{setPortalProps:function(e){n.setState({nodeProps:e})}})},n.state={nodeProps:n.props.node.getInitialPortalProps()},n}return t.prototype.componentDidMount=function(){this.addPropsChannel()},t.prototype.componentDidUpdate=function(){this.addPropsChannel()},t.prototype.render=function(){var e=this,t=this.props,n=t.children,r=t.node;return s.createPortal(o.Children.map(n,function(t){return o.isValidElement(t)?o.cloneElement(t,e.state.nodeProps):t}),r.element)},t}(o.PureComponent),h=function(e){c(t,e);function t(t){var n=e.call(this,t)||this;return n.placeholderNode=o.createRef(),n.passPropsThroughPortal(),n}return t.prototype.passPropsThroughPortal=function(){var e=Object.assign({},this.props,{node:void 0});this.props.node.setPortalProps(e)},t.prototype.componentDidMount=function(){var e=this.props.node;this.currentPortalNode=e;var t=this.placeholderNode.current,n=t.parentNode;e.mount(n,t),this.passPropsThroughPortal()},t.prototype.componentDidUpdate=function(){var e=this.props.node;this.currentPortalNode&&e!==this.currentPortalNode&&(this.currentPortalNode.unmount(this.placeholderNode.current),this.currentPortalNode.setPortalProps({}),this.currentPortalNode=e);var t=this.placeholderNode.current,n=t.parentNode;e.mount(n,t),this.passPropsThroughPortal()},t.prototype.componentWillUnmount=function(){var e=this.props.node;e.unmount(this.placeholderNode.current),e.setPortalProps({})},t.prototype.render=function(){return o.createElement(`div`,{ref:this.placeholderNode})},t}(o.PureComponent),g=p.bind(null,l);p.bind(null,u),t();var _=o.createContext({hasProvider:!1});function v(){return o.useContext(_)}var y=50;function b(e,t){let n=i(a.chunk(e,y).map(e=>t(a.uniq(e)))),r=a.flatten(n.data);return{itemsArr:r,items:n.data.length?r.reduce((e,t)=>({...e,[t.id]:t}),{}):null,isFetching:n.isFetching,hasCompleted:n.hasCompleted}}function x(e,t,n){let r=n??(e=>typeof e==`object`?e.id:e),{fetchItems:i,...a}=S({getRequest:t,_getKey:n});return o.useEffect(()=>{e?.length&&i(e)},[e?.map(r).join(`,`)]),a}function S(e){let t=e._getKey??(e=>typeof e==`object`?e.id:e),n=o.useRef(new Set),[r,s]=o.useState([]);function c(r){if(!r?.length)return;let i=[];r.forEach(e=>{let r=t(e);n.current.has(r)||(i.push(e),n.current.add(r))}),i.length&&s(t=>[...t,...a.chunk(i,y).map(e.getRequest)])}let l=i(r),u=a.flatten(l.data),d=l.data.length?u.reduce((e,n)=>({...e,[t(n)]:n}),{}):null;return{hasFirstRequestCompleted:!!l.responses?.[0]?.hasCompleted,itemsArr:u,items:d,isFetching:l.isFetching,fetchItems:c}}export{h as a,m as i,x as n,g as o,v as r,b as t};
2
- //# sourceMappingURL=B3UVC04b.chunk.js.map
1
+ import{Dr as e,N as t,at as n,it as r}from"./CrTgNROp.chunk.js";import{h as i}from"./Dwe-4MVf.chunk.js";import{t as a}from"./o2slFZEB.chunk.js";import"./HeoWyBUD.chunk.js";import"./app-B1NVV4PT.js";var o=e(n()),s=e(r()),c=(function(){var e=function(t,n){return e=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},e(t,n)};return function(t,n){e(t,n);function r(){this.constructor=t}t.prototype=n===null?Object.create(n):(r.prototype=n.prototype,new r)}})(),l=`html`,u=`svg`,d=`http://www.w3.org/2000/svg`,f=function(e,t){if(t===l)return e instanceof HTMLElement;if(t===u)return e instanceof SVGElement;throw Error(`Unrecognized element type "`+t+`" for validateElementType.`)},p=function(e,t){var n={},r,i,a;if(e===l)a=document.createElement(`div`);else if(e===u)a=document.createElementNS(d,`g`);else throw Error(`Invalid element type "`+e+`" for createPortalNode: must be "html" or "svg".`);if(t&&typeof t==`object`)for(var o=0,s=Object.entries(t.attributes);o<s.length;o++){var c=s[o],p=c[0],m=c[1];a.setAttribute(p,m)}var h={element:a,elementType:e,setPortalProps:function(e){n=e},getInitialPortalProps:function(){return n},mount:function(t,n){if(n!==i){if(h.unmount(),t!==r&&!f(t,e))throw Error(`Invalid element type for portal: "`+e+`" portalNodes must be used with `+e+` elements, but OutPortal is within <`+t.tagName+`>.`);t.replaceChild(h.element,n),r=t,i=n}},unmount:function(e){e&&e!==i||r&&i&&(r.replaceChild(i,h.element),r=void 0,i=void 0)}};return h},m=function(e){c(t,e);function t(t){var n=e.call(this,t)||this;return n.addPropsChannel=function(){Object.assign(n.props.node,{setPortalProps:function(e){n.setState({nodeProps:e})}})},n.state={nodeProps:n.props.node.getInitialPortalProps()},n}return t.prototype.componentDidMount=function(){this.addPropsChannel()},t.prototype.componentDidUpdate=function(){this.addPropsChannel()},t.prototype.render=function(){var e=this,t=this.props,n=t.children,r=t.node;return s.createPortal(o.Children.map(n,function(t){return o.isValidElement(t)?o.cloneElement(t,e.state.nodeProps):t}),r.element)},t}(o.PureComponent),h=function(e){c(t,e);function t(t){var n=e.call(this,t)||this;return n.placeholderNode=o.createRef(),n.passPropsThroughPortal(),n}return t.prototype.passPropsThroughPortal=function(){var e=Object.assign({},this.props,{node:void 0});this.props.node.setPortalProps(e)},t.prototype.componentDidMount=function(){var e=this.props.node;this.currentPortalNode=e;var t=this.placeholderNode.current,n=t.parentNode;e.mount(n,t),this.passPropsThroughPortal()},t.prototype.componentDidUpdate=function(){var e=this.props.node;this.currentPortalNode&&e!==this.currentPortalNode&&(this.currentPortalNode.unmount(this.placeholderNode.current),this.currentPortalNode.setPortalProps({}),this.currentPortalNode=e);var t=this.placeholderNode.current,n=t.parentNode;e.mount(n,t),this.passPropsThroughPortal()},t.prototype.componentWillUnmount=function(){var e=this.props.node;e.unmount(this.placeholderNode.current),e.setPortalProps({})},t.prototype.render=function(){return o.createElement(`div`,{ref:this.placeholderNode})},t}(o.PureComponent),g=p.bind(null,l);p.bind(null,u),t();var _=o.createContext({hasProvider:!1});function v(){return o.useContext(_)}var y=50;function b(e,t){let n=i(a.chunk(e,y).map(e=>t(a.uniq(e)))),r=a.flatten(n.data);return{itemsArr:r,items:n.data.length?r.reduce((e,t)=>({...e,[t.id]:t}),{}):null,isFetching:n.isFetching,hasCompleted:n.hasCompleted}}function x(e,t,n){let r=n??(e=>typeof e==`object`?e.id:e),{fetchItems:i,...a}=S({getRequest:t,_getKey:n});return o.useEffect(()=>{e?.length&&i(e)},[e?.map(r).join(`,`)]),a}function S(e){let t=e._getKey??(e=>typeof e==`object`?e.id:e),n=o.useRef(new Set),[r,s]=o.useState([]);function c(r){if(!r?.length)return;let i=[];r.forEach(e=>{let r=t(e);n.current.has(r)||(i.push(e),n.current.add(r))}),i.length&&s(t=>[...t,...a.chunk(i,y).map(e.getRequest)])}let l=i(r),u=a.flatten(l.data),d=l.data.length?u.reduce((e,n)=>({...e,[t(n)]:n}),{}):null;return{hasFirstRequestCompleted:!!l.responses?.[0]?.hasCompleted,itemsArr:u,items:d,isFetching:l.isFetching,fetchItems:c}}export{h as a,m as i,x as n,g as o,v as r,b as t};
2
+ //# sourceMappingURL=TzLygaBE.chunk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"B3UVC04b.chunk.js","names":[],"sources":["../../../../../node_modules/react-reverse-portal/dist/web/index.js","../../../../libs/shared/src/context/player-context/PlayerContext.tsx","../../../../libs/shared/src/hooks/UseBatchFetch.ts"],"sourcesContent":["var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\n// Internally, the portalNode must be for either HTML or SVG elements\nvar ELEMENT_TYPE_HTML = 'html';\nvar ELEMENT_TYPE_SVG = 'svg';\n// ReactDOM can handle several different namespaces, but they're not exported publicly\n// https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/shared/DOMNamespaces.js#L8-L10\nvar SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\nvar validateElementType = function (domElement, elementType) {\n if (elementType === ELEMENT_TYPE_HTML) {\n return domElement instanceof HTMLElement;\n }\n if (elementType === ELEMENT_TYPE_SVG) {\n return domElement instanceof SVGElement;\n }\n throw new Error(\"Unrecognized element type \\\"\" + elementType + \"\\\" for validateElementType.\");\n};\n// This is the internal implementation: the public entry points set elementType to an appropriate value\nvar createPortalNode = function (elementType, options) {\n var initialProps = {};\n var parent;\n var lastPlaceholder;\n var element;\n if (elementType === ELEMENT_TYPE_HTML) {\n element = document.createElement('div');\n }\n else if (elementType === ELEMENT_TYPE_SVG) {\n element = document.createElementNS(SVG_NAMESPACE, 'g');\n }\n else {\n throw new Error(\"Invalid element type \\\"\" + elementType + \"\\\" for createPortalNode: must be \\\"html\\\" or \\\"svg\\\".\");\n }\n if (options && typeof options === \"object\") {\n for (var _i = 0, _a = Object.entries(options.attributes); _i < _a.length; _i++) {\n var _b = _a[_i], key = _b[0], value = _b[1];\n element.setAttribute(key, value);\n }\n }\n var portalNode = {\n element: element,\n elementType: elementType,\n setPortalProps: function (props) {\n initialProps = props;\n },\n getInitialPortalProps: function () {\n return initialProps;\n },\n mount: function (newParent, newPlaceholder) {\n if (newPlaceholder === lastPlaceholder) {\n // Already mounted - noop.\n return;\n }\n portalNode.unmount();\n // To support SVG and other non-html elements, the portalNode's elementType needs to match\n // the elementType it's being rendered into\n if (newParent !== parent) {\n if (!validateElementType(newParent, elementType)) {\n throw new Error(\"Invalid element type for portal: \\\"\" + elementType + \"\\\" portalNodes must be used with \" + elementType + \" elements, but OutPortal is within <\" + newParent.tagName + \">.\");\n }\n }\n newParent.replaceChild(portalNode.element, newPlaceholder);\n parent = newParent;\n lastPlaceholder = newPlaceholder;\n },\n unmount: function (expectedPlaceholder) {\n if (expectedPlaceholder && expectedPlaceholder !== lastPlaceholder) {\n // Skip unmounts for placeholders that aren't currently mounted\n // They will have been automatically unmounted already by a subsequent mount()\n return;\n }\n if (parent && lastPlaceholder) {\n parent.replaceChild(lastPlaceholder, portalNode.element);\n parent = undefined;\n lastPlaceholder = undefined;\n }\n }\n };\n return portalNode;\n};\nvar InPortal = /** @class */ (function (_super) {\n __extends(InPortal, _super);\n function InPortal(props) {\n var _this = _super.call(this, props) || this;\n _this.addPropsChannel = function () {\n Object.assign(_this.props.node, {\n setPortalProps: function (props) {\n // Rerender the child node here if/when the out portal props change\n _this.setState({ nodeProps: props });\n }\n });\n };\n _this.state = {\n nodeProps: _this.props.node.getInitialPortalProps(),\n };\n return _this;\n }\n InPortal.prototype.componentDidMount = function () {\n this.addPropsChannel();\n };\n InPortal.prototype.componentDidUpdate = function () {\n this.addPropsChannel();\n };\n InPortal.prototype.render = function () {\n var _this = this;\n var _a = this.props, children = _a.children, node = _a.node;\n return ReactDOM.createPortal(React.Children.map(children, function (child) {\n if (!React.isValidElement(child))\n return child;\n return React.cloneElement(child, _this.state.nodeProps);\n }), node.element);\n };\n return InPortal;\n}(React.PureComponent));\nvar OutPortal = /** @class */ (function (_super) {\n __extends(OutPortal, _super);\n function OutPortal(props) {\n var _this = _super.call(this, props) || this;\n _this.placeholderNode = React.createRef();\n _this.passPropsThroughPortal();\n return _this;\n }\n OutPortal.prototype.passPropsThroughPortal = function () {\n var propsForTarget = Object.assign({}, this.props, { node: undefined });\n this.props.node.setPortalProps(propsForTarget);\n };\n OutPortal.prototype.componentDidMount = function () {\n var node = this.props.node;\n this.currentPortalNode = node;\n var placeholder = this.placeholderNode.current;\n var parent = placeholder.parentNode;\n node.mount(parent, placeholder);\n this.passPropsThroughPortal();\n };\n OutPortal.prototype.componentDidUpdate = function () {\n // We re-mount on update, just in case we were unmounted (e.g. by\n // a second OutPortal, which has now been removed)\n var node = this.props.node;\n // If we're switching portal nodes, we need to clean up the current one first.\n if (this.currentPortalNode && node !== this.currentPortalNode) {\n this.currentPortalNode.unmount(this.placeholderNode.current);\n this.currentPortalNode.setPortalProps({});\n this.currentPortalNode = node;\n }\n var placeholder = this.placeholderNode.current;\n var parent = placeholder.parentNode;\n node.mount(parent, placeholder);\n this.passPropsThroughPortal();\n };\n OutPortal.prototype.componentWillUnmount = function () {\n var node = this.props.node;\n node.unmount(this.placeholderNode.current);\n node.setPortalProps({});\n };\n OutPortal.prototype.render = function () {\n // Render a placeholder to the DOM, so we can get a reference into\n // our location in the DOM, and swap it out for the portaled node.\n // A <div> placeholder works fine even for SVG.\n return React.createElement(\"div\", { ref: this.placeholderNode });\n };\n return OutPortal;\n}(React.PureComponent));\nvar createHtmlPortalNode = createPortalNode.bind(null, ELEMENT_TYPE_HTML);\nvar createSvgPortalNode = createPortalNode.bind(null, ELEMENT_TYPE_SVG);\nexport { createHtmlPortalNode, createSvgPortalNode, InPortal, OutPortal, };\n//# sourceMappingURL=index.js.map","import React from 'react';\nimport { createHtmlPortalNode, HtmlPortalNode } from 'react-reverse-portal';\n\nimport { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nimport { DefaultDisplayMode, PlayerInitializationData } from 'libs/shared/context/player-context/interfaces/PlayerContextAction';\nimport { PlayerContextState } from 'libs/shared/context/player-context/interfaces/PlayerContextState';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { playerContextReducer } from 'libs/shared/context/player-context/reducer/PlayerContextReducer';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\n\nconst _THEATRE_MODE = 'play-page-theatre-mode';\n\nexport interface PlayerContextValues extends PlayerContextState {\n playerRef?: React.MutableRefObject<PlayerReference>;\n portalNode?: HtmlPortalNode;\n questionListPortalNode?: HtmlPortalNode;\n\n useInitialize?: (initializeData: PlayerInitializationData) => void;\n dispose?: () => void;\n setPlayerRef?: (player: any) => void;\n setPlayerMode?: (mode: PlayerMode) => void;\n setDefaultDisplayMode?: (displayMode: DefaultDisplayMode) => void;\n setStarted?: (started: boolean) => void;\n setPersist?: () => void;\n\n /**\n * Tells components if an instance of <PlayerContextProvider /> exists\n * above them in the tree. I.e. When this is used in curator.\n */\n hasProvider: boolean;\n}\n\nconst PlayerContext = React.createContext<PlayerContextValues>({ hasProvider: false });\n\nexport function usePlayerContext() {\n return React.useContext(PlayerContext);\n}\n\nfunction getInitialState(): PlayerContextState {\n const hasSavedTheatreMode = LocalStorageHelper.get(_THEATRE_MODE);\n\n return {\n defaultDisplayMode: hasSavedTheatreMode ? 'theatre' : 'normal'\n };\n}\n\nexport function PlayerContextProvider(props: React.PropsWithChildren) {\n const [ state, dispatch ] = React.useReducer(playerContextReducer, getInitialState());\n const { hasPreviewVideos } = useSettings(null);\n\n const playerRef = React.useRef<any>(null);\n\n const portalNode = React.useMemo(() => createHtmlPortalNode(\n { attributes: { class: 'cv-theatre-mode-video-container' } }\n ), []);\n\n const questionListPortalNode = React.useMemo(createHtmlPortalNode, []);\n\n function setPlayerRef(player: PlayerReference) {\n playerRef.current = player;\n }\n\n function useInitialize(initializeData: PlayerInitializationData) {\n const enabled = hasPreviewVideos || initializeData.mode !== 'hover';\n\n React.useEffect(() => {\n if (!enabled)\n return;\n\n /**\n * Cannot initialize a hover player if we already have a player elsewhere.\n */\n if (initializeData.mode === 'hover' && state.mode)\n return;\n\n /**\n * No hover to play on interactives. This feature is ComingSoon™️ - Sha\n */\n if (initializeData.mode === 'hover' && initializeData.objectTypeId === MasterType.Interactive)\n return;\n\n dispatch({\n type: 'initialize',\n data: initializeData\n });\n\n return disposeInternal;\n }, []);\n }\n\n function setPlayerMode(mode: PlayerMode) {\n dispatch({ type: 'mode', data: { mode } });\n }\n\n function setDefaultDisplayMode(defaultDisplayMode: DefaultDisplayMode) {\n LocalStorageHelper.set(_THEATRE_MODE, defaultDisplayMode === 'theatre');\n\n dispatch({ type: 'defaultDisplayMode', data: { defaultDisplayMode } });\n }\n\n function setStarted(): void {\n dispatch({ type: 'started' });\n }\n\n function disposeInternal(force: boolean = false): void {\n if (force) {\n playerRef.current = null;\n }\n\n dispatch({ type: 'dispose', data: { force: force } });\n }\n\n function setPersist(): void {\n dispatch({ type: 'persist' });\n }\n\n /**\n * If anything external calls dispose, we ignore the persist flag and force a disposal\n */\n function dispose(): void {\n disposeInternal(true);\n }\n\n const playerContextValues: PlayerContextValues = {\n ...state,\n playerRef,\n setPlayerRef,\n portalNode,\n questionListPortalNode,\n useInitialize,\n setPlayerMode,\n setDefaultDisplayMode,\n setStarted,\n dispose,\n setPersist,\n hasProvider: true\n };\n\n return (\n <PlayerContext.Provider value={playerContextValues}>\n {props.children}\n </PlayerContext.Provider>\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { BaseObject } from 'libs/shared/interfaces';\n\nconst CHUNK_SIZE = 50;\n\nexport interface UseBatchFetchResult<T extends BaseObject> {\n itemsArr: T[];\n items: {[key: string]: T } | null;\n isFetching: boolean;\n hasCompleted: boolean;\n}\n\n/**\n * Used to fetch multiple items by id with Flight. Will fetch 25 items at a time firing off multiple\n * requests if there are more than 25 items.\n * This will return items as null until we have all our items. Items will be returned as an object with\n * their ids as they key for easy mapping\n * \n * @param itemIds \n * @param getRequest \n */\nexport function useBatchFetch<T extends BaseObject>(\n itemIds: string[],\n getRequest: (ids: string[]) => Flight.Request\n): UseBatchFetchResult<T> {\n const chunks = ArrayHelper.chunk<string>(itemIds, CHUNK_SIZE);\n\n const requests = chunks.map(chunk => getRequest(ArrayHelper.uniq(chunk)));\n\n const responses = Flight.useBasicFetchAll<T[]>(requests);\n\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length ?\n itemsArr.reduce((acc, item) => ({ ...acc, [item.id]: item }), {}) :\n null;\n\n return {\n itemsArr,\n items,\n isFetching: responses.isFetching,\n hasCompleted: responses.hasCompleted\n };\n}\n\n/**\n * When you need the useBatchFetch() behavior, but your list of objects to hydrate\n * will grow, such as on a scrolling page. useGrowingBatchFetch() will use local state\n * to determine what we've already built a request for and what items are new\n * as to not re-fetch items - Sha\n */\nexport function useGrowingBatchFetch<TResponse, TObjects = string>(\n objs: TObjects[],\n getRequest: (items: TObjects[]) => Flight.Request,\n _getKey?: (obj: TObjects) => string\n) {\n const getKey = _getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const { fetchItems, ...data } = useGrowingBatchFetchFunc<TResponse, TObjects>({ getRequest, _getKey });\n\n React.useEffect(() => {\n if (!objs?.length)\n return;\n\n fetchItems(objs);\n }, [objs?.map(getKey).join(',')]);\n\n return data;\n}\n\ninterface UseGrowingBatchFetchFuncOptions<TObjects> {\n getRequest: (items: TObjects[]) => Flight.Request;\n _getKey?: (obj: TObjects) => string;\n}\n\n/**\n * When you need the useGrowingBatchFetch() behaviour, but need to trigger the\n * fetch manually and update the objects - Nish \n */\nexport function useGrowingBatchFetchFunc<TResponse, TObjects = string>(\n options: UseGrowingBatchFetchFuncOptions<TObjects>\n) {\n const getKey = options._getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const fetchedItems = React.useRef<Set<string>>(new Set<string>());\n const [ requests, setRequests ] = React.useState<Flight.Request[]>([]);\n\n function fetchItems(objs: TObjects[]) {\n if (!objs?.length)\n return;\n\n const unfetchedItems: TObjects[] = [];\n \n objs.forEach(obj => {\n const key = getKey(obj);\n\n if (fetchedItems.current.has(key))\n return;\n\n unfetchedItems.push(obj);\n fetchedItems.current.add(key);\n });\n \n if (!unfetchedItems.length)\n return;\n \n setRequests(r => ([ ...r, ...ArrayHelper.chunk<TObjects>(unfetchedItems, CHUNK_SIZE).map(options.getRequest) ]));\n }\n\n const responses = Flight.useBasicFetchAll<TResponse[]>(requests);\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length ?\n itemsArr.reduce<Record<string, TResponse>>((acc, item) => ({ ...acc, [getKey(item)]: item }), {}) :\n null;\n\n return {\n hasFirstRequestCompleted: !!responses.responses?.[0]?.hasCompleted,\n itemsArr,\n items,\n isFetching: responses.isFetching,\n fetchItems\n };\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}
1
+ {"version":3,"file":"TzLygaBE.chunk.js","names":[],"sources":["../../../../../node_modules/react-reverse-portal/dist/web/index.js","../../../../libs/shared/src/context/player-context/PlayerContext.tsx","../../../../libs/shared/src/hooks/UseBatchFetch.ts"],"sourcesContent":["var __extends = (this && this.__extends) || (function () {\n var extendStatics = function (d, b) {\n extendStatics = Object.setPrototypeOf ||\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\n return extendStatics(d, b);\n };\n return function (d, b) {\n extendStatics(d, b);\n function __() { this.constructor = d; }\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\n };\n})();\nimport * as React from 'react';\nimport * as ReactDOM from 'react-dom';\n// Internally, the portalNode must be for either HTML or SVG elements\nvar ELEMENT_TYPE_HTML = 'html';\nvar ELEMENT_TYPE_SVG = 'svg';\n// ReactDOM can handle several different namespaces, but they're not exported publicly\n// https://github.com/facebook/react/blob/b87aabdfe1b7461e7331abb3601d9e6bb27544bc/packages/react-dom/src/shared/DOMNamespaces.js#L8-L10\nvar SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\nvar validateElementType = function (domElement, elementType) {\n if (elementType === ELEMENT_TYPE_HTML) {\n return domElement instanceof HTMLElement;\n }\n if (elementType === ELEMENT_TYPE_SVG) {\n return domElement instanceof SVGElement;\n }\n throw new Error(\"Unrecognized element type \\\"\" + elementType + \"\\\" for validateElementType.\");\n};\n// This is the internal implementation: the public entry points set elementType to an appropriate value\nvar createPortalNode = function (elementType, options) {\n var initialProps = {};\n var parent;\n var lastPlaceholder;\n var element;\n if (elementType === ELEMENT_TYPE_HTML) {\n element = document.createElement('div');\n }\n else if (elementType === ELEMENT_TYPE_SVG) {\n element = document.createElementNS(SVG_NAMESPACE, 'g');\n }\n else {\n throw new Error(\"Invalid element type \\\"\" + elementType + \"\\\" for createPortalNode: must be \\\"html\\\" or \\\"svg\\\".\");\n }\n if (options && typeof options === \"object\") {\n for (var _i = 0, _a = Object.entries(options.attributes); _i < _a.length; _i++) {\n var _b = _a[_i], key = _b[0], value = _b[1];\n element.setAttribute(key, value);\n }\n }\n var portalNode = {\n element: element,\n elementType: elementType,\n setPortalProps: function (props) {\n initialProps = props;\n },\n getInitialPortalProps: function () {\n return initialProps;\n },\n mount: function (newParent, newPlaceholder) {\n if (newPlaceholder === lastPlaceholder) {\n // Already mounted - noop.\n return;\n }\n portalNode.unmount();\n // To support SVG and other non-html elements, the portalNode's elementType needs to match\n // the elementType it's being rendered into\n if (newParent !== parent) {\n if (!validateElementType(newParent, elementType)) {\n throw new Error(\"Invalid element type for portal: \\\"\" + elementType + \"\\\" portalNodes must be used with \" + elementType + \" elements, but OutPortal is within <\" + newParent.tagName + \">.\");\n }\n }\n newParent.replaceChild(portalNode.element, newPlaceholder);\n parent = newParent;\n lastPlaceholder = newPlaceholder;\n },\n unmount: function (expectedPlaceholder) {\n if (expectedPlaceholder && expectedPlaceholder !== lastPlaceholder) {\n // Skip unmounts for placeholders that aren't currently mounted\n // They will have been automatically unmounted already by a subsequent mount()\n return;\n }\n if (parent && lastPlaceholder) {\n parent.replaceChild(lastPlaceholder, portalNode.element);\n parent = undefined;\n lastPlaceholder = undefined;\n }\n }\n };\n return portalNode;\n};\nvar InPortal = /** @class */ (function (_super) {\n __extends(InPortal, _super);\n function InPortal(props) {\n var _this = _super.call(this, props) || this;\n _this.addPropsChannel = function () {\n Object.assign(_this.props.node, {\n setPortalProps: function (props) {\n // Rerender the child node here if/when the out portal props change\n _this.setState({ nodeProps: props });\n }\n });\n };\n _this.state = {\n nodeProps: _this.props.node.getInitialPortalProps(),\n };\n return _this;\n }\n InPortal.prototype.componentDidMount = function () {\n this.addPropsChannel();\n };\n InPortal.prototype.componentDidUpdate = function () {\n this.addPropsChannel();\n };\n InPortal.prototype.render = function () {\n var _this = this;\n var _a = this.props, children = _a.children, node = _a.node;\n return ReactDOM.createPortal(React.Children.map(children, function (child) {\n if (!React.isValidElement(child))\n return child;\n return React.cloneElement(child, _this.state.nodeProps);\n }), node.element);\n };\n return InPortal;\n}(React.PureComponent));\nvar OutPortal = /** @class */ (function (_super) {\n __extends(OutPortal, _super);\n function OutPortal(props) {\n var _this = _super.call(this, props) || this;\n _this.placeholderNode = React.createRef();\n _this.passPropsThroughPortal();\n return _this;\n }\n OutPortal.prototype.passPropsThroughPortal = function () {\n var propsForTarget = Object.assign({}, this.props, { node: undefined });\n this.props.node.setPortalProps(propsForTarget);\n };\n OutPortal.prototype.componentDidMount = function () {\n var node = this.props.node;\n this.currentPortalNode = node;\n var placeholder = this.placeholderNode.current;\n var parent = placeholder.parentNode;\n node.mount(parent, placeholder);\n this.passPropsThroughPortal();\n };\n OutPortal.prototype.componentDidUpdate = function () {\n // We re-mount on update, just in case we were unmounted (e.g. by\n // a second OutPortal, which has now been removed)\n var node = this.props.node;\n // If we're switching portal nodes, we need to clean up the current one first.\n if (this.currentPortalNode && node !== this.currentPortalNode) {\n this.currentPortalNode.unmount(this.placeholderNode.current);\n this.currentPortalNode.setPortalProps({});\n this.currentPortalNode = node;\n }\n var placeholder = this.placeholderNode.current;\n var parent = placeholder.parentNode;\n node.mount(parent, placeholder);\n this.passPropsThroughPortal();\n };\n OutPortal.prototype.componentWillUnmount = function () {\n var node = this.props.node;\n node.unmount(this.placeholderNode.current);\n node.setPortalProps({});\n };\n OutPortal.prototype.render = function () {\n // Render a placeholder to the DOM, so we can get a reference into\n // our location in the DOM, and swap it out for the portaled node.\n // A <div> placeholder works fine even for SVG.\n return React.createElement(\"div\", { ref: this.placeholderNode });\n };\n return OutPortal;\n}(React.PureComponent));\nvar createHtmlPortalNode = createPortalNode.bind(null, ELEMENT_TYPE_HTML);\nvar createSvgPortalNode = createPortalNode.bind(null, ELEMENT_TYPE_SVG);\nexport { createHtmlPortalNode, createSvgPortalNode, InPortal, OutPortal, };\n//# sourceMappingURL=index.js.map","import React from 'react';\nimport { createHtmlPortalNode, HtmlPortalNode } from 'react-reverse-portal';\n\nimport { LocalStorageHelper } from 'libs/common/backbone/utils/LocalStorageHelper';\n\nimport { DefaultDisplayMode, PlayerInitializationData } from 'libs/shared/context/player-context/interfaces/PlayerContextAction';\nimport { PlayerContextState } from 'libs/shared/context/player-context/interfaces/PlayerContextState';\nimport { PlayerMode } from 'libs/shared/context/player-context/interfaces/PlayerMode';\nimport { PlayerReference } from 'libs/shared/context/player-context/interfaces/PlayerReference';\nimport { playerContextReducer } from 'libs/shared/context/player-context/reducer/PlayerContextReducer';\nimport { MasterType } from 'libs/shared/enums/MasterType';\nimport { useSettings } from 'libs/shared/hooks/useSettings';\n\nconst _THEATRE_MODE = 'play-page-theatre-mode';\n\nexport interface PlayerContextValues extends PlayerContextState {\n playerRef?: React.MutableRefObject<PlayerReference>;\n portalNode?: HtmlPortalNode;\n questionListPortalNode?: HtmlPortalNode;\n\n useInitialize?: (initializeData: PlayerInitializationData) => void;\n dispose?: () => void;\n setPlayerRef?: (player: any) => void;\n setPlayerMode?: (mode: PlayerMode) => void;\n setDefaultDisplayMode?: (displayMode: DefaultDisplayMode) => void;\n setStarted?: (started: boolean) => void;\n setPersist?: () => void;\n\n /**\n * Tells components if an instance of <PlayerContextProvider /> exists\n * above them in the tree. I.e. When this is used in curator.\n */\n hasProvider: boolean;\n}\n\nconst PlayerContext = React.createContext<PlayerContextValues>({ hasProvider: false });\n\nexport function usePlayerContext() {\n return React.useContext(PlayerContext);\n}\n\nfunction getInitialState(): PlayerContextState {\n const hasSavedTheatreMode = LocalStorageHelper.get(_THEATRE_MODE);\n\n return {\n defaultDisplayMode: hasSavedTheatreMode ? 'theatre' : 'normal'\n };\n}\n\nexport function PlayerContextProvider(props: React.PropsWithChildren) {\n const [ state, dispatch ] = React.useReducer(playerContextReducer, getInitialState());\n const { hasPreviewVideos } = useSettings(null);\n\n const playerRef = React.useRef<any>(null);\n\n const portalNode = React.useMemo(() => createHtmlPortalNode(\n { attributes: { class: 'cv-theatre-mode-video-container' } }\n ), []);\n\n const questionListPortalNode = React.useMemo(createHtmlPortalNode, []);\n\n function setPlayerRef(player: PlayerReference) {\n playerRef.current = player;\n }\n\n function useInitialize(initializeData: PlayerInitializationData) {\n const enabled = hasPreviewVideos || initializeData.mode !== 'hover';\n\n React.useEffect(() => {\n if (!enabled)\n return;\n\n /**\n * Cannot initialize a hover player if we already have a player elsewhere.\n */\n if (initializeData.mode === 'hover' && state.mode)\n return;\n\n /**\n * No hover to play on interactives. This feature is ComingSoon™️ - Sha\n */\n if (initializeData.mode === 'hover' && initializeData.objectTypeId === MasterType.Interactive)\n return;\n\n dispatch({\n type: 'initialize',\n data: initializeData\n });\n\n return disposeInternal;\n }, []);\n }\n\n function setPlayerMode(mode: PlayerMode) {\n dispatch({ type: 'mode', data: { mode } });\n }\n\n function setDefaultDisplayMode(defaultDisplayMode: DefaultDisplayMode) {\n LocalStorageHelper.set(_THEATRE_MODE, defaultDisplayMode === 'theatre');\n\n dispatch({ type: 'defaultDisplayMode', data: { defaultDisplayMode } });\n }\n\n function setStarted(): void {\n dispatch({ type: 'started' });\n }\n\n function disposeInternal(force: boolean = false): void {\n if (force) {\n playerRef.current = null;\n }\n\n dispatch({ type: 'dispose', data: { force: force } });\n }\n\n function setPersist(): void {\n dispatch({ type: 'persist' });\n }\n\n /**\n * If anything external calls dispose, we ignore the persist flag and force a disposal\n */\n function dispose(): void {\n disposeInternal(true);\n }\n\n const playerContextValues: PlayerContextValues = {\n ...state,\n playerRef,\n setPlayerRef,\n portalNode,\n questionListPortalNode,\n useInitialize,\n setPlayerMode,\n setDefaultDisplayMode,\n setStarted,\n dispose,\n setPersist,\n hasProvider: true\n };\n\n return (\n <PlayerContext.Provider value={playerContextValues}>\n {props.children}\n </PlayerContext.Provider>\n );\n}\n","import React from 'react';\n\nimport { Flight } from 'libs/common/flight';\nimport { ArrayHelper } from 'libs/common/react/utils/ArrayHelper';\n\nimport { BaseObject } from 'libs/shared/interfaces';\n\nconst CHUNK_SIZE = 50;\n\nexport interface UseBatchFetchResult<T extends BaseObject> {\n itemsArr: T[];\n items: {[key: string]: T } | null;\n isFetching: boolean;\n hasCompleted: boolean;\n}\n\n/**\n * Used to fetch multiple items by id with Flight. Will fetch 25 items at a time firing off multiple\n * requests if there are more than 25 items.\n * This will return items as null until we have all our items. Items will be returned as an object with\n * their ids as they key for easy mapping\n * \n * @param itemIds \n * @param getRequest \n */\nexport function useBatchFetch<T extends BaseObject>(\n itemIds: string[],\n getRequest: (ids: string[]) => Flight.Request\n): UseBatchFetchResult<T> {\n const chunks = ArrayHelper.chunk<string>(itemIds, CHUNK_SIZE);\n\n const requests = chunks.map(chunk => getRequest(ArrayHelper.uniq(chunk)));\n\n const responses = Flight.useBasicFetchAll<T[]>(requests);\n\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length ?\n itemsArr.reduce((acc, item) => ({ ...acc, [item.id]: item }), {}) :\n null;\n\n return {\n itemsArr,\n items,\n isFetching: responses.isFetching,\n hasCompleted: responses.hasCompleted\n };\n}\n\n/**\n * When you need the useBatchFetch() behavior, but your list of objects to hydrate\n * will grow, such as on a scrolling page. useGrowingBatchFetch() will use local state\n * to determine what we've already built a request for and what items are new\n * as to not re-fetch items - Sha\n */\nexport function useGrowingBatchFetch<TResponse, TObjects = string>(\n objs: TObjects[],\n getRequest: (items: TObjects[]) => Flight.Request,\n _getKey?: (obj: TObjects) => string\n) {\n const getKey = _getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const { fetchItems, ...data } = useGrowingBatchFetchFunc<TResponse, TObjects>({ getRequest, _getKey });\n\n React.useEffect(() => {\n if (!objs?.length)\n return;\n\n fetchItems(objs);\n }, [objs?.map(getKey).join(',')]);\n\n return data;\n}\n\ninterface UseGrowingBatchFetchFuncOptions<TObjects> {\n getRequest: (items: TObjects[]) => Flight.Request;\n _getKey?: (obj: TObjects) => string;\n}\n\n/**\n * When you need the useGrowingBatchFetch() behaviour, but need to trigger the\n * fetch manually and update the objects - Nish \n */\nexport function useGrowingBatchFetchFunc<TResponse, TObjects = string>(\n options: UseGrowingBatchFetchFuncOptions<TObjects>\n) {\n const getKey = options._getKey ?? ((obj: any) => {\n if (typeof obj === 'object')\n return obj.id;\n\n return obj;\n });\n\n const fetchedItems = React.useRef<Set<string>>(new Set<string>());\n const [ requests, setRequests ] = React.useState<Flight.Request[]>([]);\n\n function fetchItems(objs: TObjects[]) {\n if (!objs?.length)\n return;\n\n const unfetchedItems: TObjects[] = [];\n \n objs.forEach(obj => {\n const key = getKey(obj);\n\n if (fetchedItems.current.has(key))\n return;\n\n unfetchedItems.push(obj);\n fetchedItems.current.add(key);\n });\n \n if (!unfetchedItems.length)\n return;\n \n setRequests(r => ([ ...r, ...ArrayHelper.chunk<TObjects>(unfetchedItems, CHUNK_SIZE).map(options.getRequest) ]));\n }\n\n const responses = Flight.useBasicFetchAll<TResponse[]>(requests);\n const itemsArr = ArrayHelper.flatten(responses.data);\n const items = responses.data.length ?\n itemsArr.reduce<Record<string, TResponse>>((acc, item) => ({ ...acc, [getKey(item)]: item }), {}) :\n null;\n\n return {\n hasFirstRequestCompleted: !!responses.responses?.[0]?.hasCompleted,\n itemsArr,\n items,\n isFetching: responses.isFetching,\n fetchItems\n };\n}\n"],"x_google_ignoreList":[0],"mappings":"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"}