1- import * as React from 'react'
2- import { WithTranslation } from 'react-i18next'
1+ import React , { useCallback , useState } from 'react'
2+ import { useTranslation } from 'react-i18next'
33import { Link } from 'react-router-dom'
44import { NotificationCenterPanelToggle , NotificationCenterPanel } from '../lib/notifications/NotificationCenterPanel.js'
55import { NotificationCenter , NoticeLevel } from '../lib/notifications/notifications.js'
66import { ErrorBoundary } from '../lib/ErrorBoundary.js'
77import { SupportPopUpToggle , SupportPopUp } from './SupportPopUp.js'
8- import { translateWithTracker , Translated } from '../lib/ReactMeteorData/ReactMeteorData.js'
8+ import { useTracker } from '../lib/ReactMeteorData/ReactMeteorData.js'
99import { CoreSystem } from '../collections/index.js'
1010import Container from 'react-bootstrap/Container'
1111import Nav from 'react-bootstrap/Nav'
@@ -19,125 +19,97 @@ interface IPropsHeader {
1919 allowDeveloper ?: boolean
2020}
2121
22- interface ITrackedPropsHeader {
23- name : string | undefined
24- }
25-
26- interface IStateHeader {
27- isNotificationCenterOpen : NoticeLevel | undefined
28- isSupportPanelOpen : boolean
29- }
22+ export default function Header ( { allowConfigure, allowTesting } : IPropsHeader ) : JSX . Element {
23+ const { t } = useTranslation ( )
3024
31- class Header extends React . Component < Translated < IPropsHeader & ITrackedPropsHeader > , IStateHeader > {
32- constructor ( props : Translated < IPropsHeader & ITrackedPropsHeader > ) {
33- super ( props )
25+ const sofieName = useTracker ( ( ) => {
26+ const coreSystem = CoreSystem . findOne ( )
3427
35- this . state = {
36- isNotificationCenterOpen : undefined ,
37- isSupportPanelOpen : false ,
38- }
39- }
28+ return coreSystem ?. name
29+ } , [ ] )
4030
41- onToggleNotifications = ( _e : React . MouseEvent < HTMLButtonElement > , filter : NoticeLevel | undefined ) => {
42- if ( this . state . isNotificationCenterOpen === filter ) {
43- filter = undefined
44- }
45- NotificationCenter . isOpen = filter !== undefined ? true : false
31+ const [ isNotificationCenterOpen , setIsNotificationCenterOpen ] = useState < NoticeLevel | undefined > ( undefined )
32+ const onToggleNotifications = useCallback (
33+ ( _e : React . MouseEvent < HTMLButtonElement > , filter : NoticeLevel | undefined ) => {
34+ setIsNotificationCenterOpen ( ( isNotificationCenterOpen ) => {
35+ if ( isNotificationCenterOpen === filter ) {
36+ filter = undefined
37+ }
38+ NotificationCenter . isOpen = filter !== undefined ? true : false
4639
47- this . setState ( {
48- isNotificationCenterOpen : filter ,
49- } )
50- }
40+ return filter
41+ } )
42+ } ,
43+ [ ]
44+ )
5145
52- onToggleSupportPanel = ( ) => {
53- this . setState ( {
54- isSupportPanelOpen : ! this . state . isSupportPanelOpen ,
55- } )
56- }
46+ const [ isSupportPanelOpen , setIsSupportPanelOpen ] = useState ( false )
47+ const onToggleSupportPanel = useCallback ( ( ) => setIsSupportPanelOpen ( ( prev ) => ! prev ) , [ ] )
5748
58- render ( ) : JSX . Element {
59- const { t } = this . props
60-
61- return (
62- < React . Fragment >
63- < ErrorBoundary >
64- < AnimatePresence >
65- { this . state . isNotificationCenterOpen !== undefined && (
66- < NotificationCenterPanel limitCount = { 15 } filter = { this . state . isNotificationCenterOpen } />
67- ) }
68- { this . state . isSupportPanelOpen && < SupportPopUp /> }
69- </ AnimatePresence >
70- </ ErrorBoundary >
71- < ErrorBoundary >
72- < div className = "status-bar" >
73- < NotificationCenterPanelToggle
74- onClick = { ( e ) => this . onToggleNotifications ( e , NoticeLevel . CRITICAL ) }
75- isOpen = { this . state . isNotificationCenterOpen === NoticeLevel . CRITICAL }
76- filter = { NoticeLevel . CRITICAL }
77- className = "type-critical"
78- title = { t ( 'Critical Problems' ) }
79- />
80- < NotificationCenterPanelToggle
81- onClick = { ( e ) => this . onToggleNotifications ( e , NoticeLevel . WARNING ) }
82- isOpen = { this . state . isNotificationCenterOpen === NoticeLevel . WARNING }
83- filter = { NoticeLevel . WARNING }
84- className = "type-warning"
85- title = { t ( 'Warnings' ) }
86- />
87- < NotificationCenterPanelToggle
88- onClick = { ( e ) => this . onToggleNotifications ( e , NoticeLevel . NOTIFICATION | NoticeLevel . TIP ) }
89- isOpen = {
90- this . state . isNotificationCenterOpen === ( ( NoticeLevel . NOTIFICATION | NoticeLevel . TIP ) as NoticeLevel )
91- }
92- filter = { NoticeLevel . NOTIFICATION | NoticeLevel . TIP }
93- className = "type-notification"
94- title = { t ( 'Notes' ) }
95- />
96- < SupportPopUpToggle onClick = { this . onToggleSupportPanel } isOpen = { this . state . isSupportPanelOpen } />
97- </ div >
98- </ ErrorBoundary >
99- < Navbar data-bs-theme = "dark" fixed = "top" expand className = "bg-body-tertiary" >
100- < Container fluid className = "mx-5" >
101- < Navbar . Brand >
102- < Link className = "badge-sofie" to = "/" >
103- < div className = "media-elem me-2 sofie-logo" />
104- < div className = "logo-text" > Sofie { this . props . name ? ' - ' + this . props . name : null } </ div >
105- </ Link >
106- </ Navbar . Brand >
107- < Nav className = "justify-content-end" >
108- < LinkContainer to = "/rundowns" activeClassName = "active" >
109- < Nav . Link > { t ( 'Rundowns' ) } </ Nav . Link >
49+ return (
50+ < React . Fragment >
51+ < ErrorBoundary >
52+ < AnimatePresence >
53+ { isNotificationCenterOpen !== undefined && (
54+ < NotificationCenterPanel limitCount = { 15 } filter = { isNotificationCenterOpen } />
55+ ) }
56+ { isSupportPanelOpen && < SupportPopUp /> }
57+ </ AnimatePresence >
58+ </ ErrorBoundary >
59+ < ErrorBoundary >
60+ < div className = "status-bar" >
61+ < NotificationCenterPanelToggle
62+ onClick = { ( e ) => onToggleNotifications ( e , NoticeLevel . CRITICAL ) }
63+ isOpen = { isNotificationCenterOpen === NoticeLevel . CRITICAL }
64+ filter = { NoticeLevel . CRITICAL }
65+ className = "type-critical"
66+ title = { t ( 'Critical Problems' ) }
67+ />
68+ < NotificationCenterPanelToggle
69+ onClick = { ( e ) => onToggleNotifications ( e , NoticeLevel . WARNING ) }
70+ isOpen = { isNotificationCenterOpen === NoticeLevel . WARNING }
71+ filter = { NoticeLevel . WARNING }
72+ className = "type-warning"
73+ title = { t ( 'Warnings' ) }
74+ />
75+ < NotificationCenterPanelToggle
76+ onClick = { ( e ) => onToggleNotifications ( e , NoticeLevel . NOTIFICATION | NoticeLevel . TIP ) }
77+ isOpen = { isNotificationCenterOpen === ( ( NoticeLevel . NOTIFICATION | NoticeLevel . TIP ) as NoticeLevel ) }
78+ filter = { NoticeLevel . NOTIFICATION | NoticeLevel . TIP }
79+ className = "type-notification"
80+ title = { t ( 'Notes' ) }
81+ />
82+ < SupportPopUpToggle onClick = { onToggleSupportPanel } isOpen = { isSupportPanelOpen } />
83+ </ div >
84+ </ ErrorBoundary >
85+ < Navbar data-bs-theme = "dark" fixed = "top" expand className = "bg-body-tertiary" >
86+ < Container fluid className = "mx-5" >
87+ < Navbar . Brand >
88+ < Link className = "badge-sofie" to = "/" >
89+ < div className = "media-elem me-2 sofie-logo" />
90+ < div className = "logo-text" > Sofie { sofieName ? ' - ' + sofieName : null } </ div >
91+ </ Link >
92+ </ Navbar . Brand >
93+ < Nav className = "justify-content-end" >
94+ < LinkContainer to = "/rundowns" activeClassName = "active" >
95+ < Nav . Link > { t ( 'Rundowns' ) } </ Nav . Link >
96+ </ LinkContainer >
97+ { allowTesting && (
98+ < LinkContainer to = "/testTools" activeClassName = "active" >
99+ < Nav . Link > { t ( 'Test Tools' ) } </ Nav . Link >
110100 </ LinkContainer >
111- { this . props . allowTesting && (
112- < LinkContainer to = "/testTools " activeClassName = "active" >
113- < Nav . Link > { t ( 'Test Tools ' ) } </ Nav . Link >
114- </ LinkContainer >
115- ) }
116- < LinkContainer to = "/status " activeClassName = "active" >
117- < Nav . Link > { t ( 'Status ' ) } </ Nav . Link >
101+ ) }
102+ < LinkContainer to = "/status " activeClassName = "active" >
103+ < Nav . Link > { t ( 'Status ' ) } </ Nav . Link >
104+ </ LinkContainer >
105+ { allowConfigure && (
106+ < LinkContainer to = "/settings " activeClassName = "active" >
107+ < Nav . Link > { t ( 'Settings ' ) } </ Nav . Link >
118108 </ LinkContainer >
119- { this . props . allowConfigure && (
120- < LinkContainer to = "/settings" activeClassName = "active" >
121- < Nav . Link > { t ( 'Settings' ) } </ Nav . Link >
122- </ LinkContainer >
123- ) }
124- </ Nav >
125- </ Container >
126- </ Navbar >
127- </ React . Fragment >
128- )
129- }
109+ ) }
110+ </ Nav >
111+ </ Container >
112+ </ Navbar >
113+ </ React . Fragment >
114+ )
130115}
131-
132- export default translateWithTracker ( ( _props : IPropsHeader & WithTranslation ) : ITrackedPropsHeader => {
133- const coreSystem = CoreSystem . findOne ( )
134- let name : string | undefined = undefined
135-
136- if ( coreSystem ) {
137- name = coreSystem . name
138- }
139-
140- return {
141- name,
142- }
143- } ) ( Header )
0 commit comments