1818 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919 */
2020
21+ import styled from '@emotion/styled' ;
22+ import { Layout } from '@sonarsource/echoes-react' ;
23+ import { noop } from 'lodash' ;
2124import * as React from 'react' ;
22- import { createPortal } from 'react-dom' ;
2325import { Helmet } from 'react-helmet-async' ;
26+ import { useIntl } from 'react-intl' ;
2427import { Outlet } from 'react-router-dom' ;
28+ import { useFlags } from '~adapters/helpers/feature-flags' ;
29+ import useEffectOnce from '~shared/helpers/useEffectOnce' ;
2530import { Extension } from '~shared/types/common' ;
2631import { getSettingsNavigation } from '~sq-server-commons/api/navigation' ;
2732import { getPendingPlugins } from '~sq-server-commons/api/plugins' ;
@@ -32,142 +37,121 @@ import AdminContext, {
3237} from '~sq-server-commons/context/AdminContext' ;
3338import withAppStateContext from '~sq-server-commons/context/app-state/withAppStateContext' ;
3439import { translate } from '~sq-server-commons/helpers/l10n' ;
35- import { getIntl } from '~sq-server-commons/helpers/l10nBundle' ;
3640import { AdminPagesContext } from '~sq-server-commons/types/admin' ;
3741import { AppState } from '~sq-server-commons/types/appstate' ;
3842import { PendingPluginResult } from '~sq-server-commons/types/plugins' ;
3943import { SysStatus } from '~sq-server-commons/types/types' ;
4044import handleRequiredAuthorization from '../utils/handleRequiredAuthorization' ;
45+ import { AdministrationSidebar } from './nav/administration/AdministrationSidebar' ;
4146import SettingsNav from './nav/settings/SettingsNav' ;
4247
4348export interface AdminContainerProps {
4449 appState : AppState ;
4550}
4651
47- interface State {
48- adminPages : Extension [ ] ;
49- pendingPlugins : PendingPluginResult ;
50- systemStatus : SysStatus ;
51- }
52-
53- export class AdminContainer extends React . PureComponent < AdminContainerProps , State > {
54- intl = getIntl ( ) ;
55- mounted = false ;
56- portalAnchor : Element | null = null ;
57- state : State = {
58- pendingPlugins : defaultPendingPlugins ,
59- systemStatus : defaultSystemStatus ,
60- adminPages : [ ] ,
61- } ;
62-
63- componentDidMount ( ) {
64- this . mounted = true ;
65- this . portalAnchor = document . getElementById ( 'component-nav-portal' ) ;
66- if ( ! this . props . appState . canAdmin ) {
52+ export function AdminContainer ( { appState } : Readonly < AdminContainerProps > ) {
53+ const intl = useIntl ( ) ;
54+
55+ const { frontEndEngineeringEnableSidebarNavigation } = useFlags ( ) ;
56+
57+ const [ pendingPlugins , setPendingPlugins ] =
58+ React . useState < PendingPluginResult > ( defaultPendingPlugins ) ;
59+ const [ systemStatus , setSystemStatus ] = React . useState < SysStatus > ( defaultSystemStatus ) ;
60+ const [ adminPages , setAdminPages ] = React . useState < Extension [ ] > ( [ ] ) ;
61+
62+ const fetchNavigationSettings = React . useCallback ( ( ) => {
63+ getSettingsNavigation ( ) . then ( ( r ) => {
64+ setAdminPages ( r . extensions ) ;
65+ } , noop ) ;
66+ } , [ ] ) ;
67+
68+ const fetchPendingPlugins = React . useCallback ( ( ) => {
69+ getPendingPlugins ( ) . then ( ( pendingPlugins ) => {
70+ setPendingPlugins ( pendingPlugins ) ;
71+ } , noop ) ;
72+ } , [ ] ) ;
73+
74+ const waitRestartingDone = React . useCallback ( ( ) => {
75+ waitSystemUPStatus ( ) . then ( ( { status } ) => {
76+ setSystemStatus ( status ) ;
77+ window . location . reload ( ) ;
78+ } , noop ) ;
79+ } , [ ] ) ;
80+
81+ const fetchSystemStatus = React . useCallback ( ( ) => {
82+ getSystemStatus ( ) . then ( ( { status } ) => {
83+ setSystemStatus ( status ) ;
84+ if ( status === 'RESTARTING' ) {
85+ waitRestartingDone ( ) ;
86+ }
87+ } , noop ) ;
88+ } , [ waitRestartingDone ] ) ;
89+
90+ useEffectOnce ( ( ) => {
91+ if ( ! appState . canAdmin ) {
6792 handleRequiredAuthorization ( ) ;
68- } else {
69- this . fetchNavigationSettings ( ) ;
70- this . fetchPendingPlugins ( ) ;
71- this . fetchSystemStatus ( ) ;
93+ return ;
7294 }
73- }
7495
75- componentWillUnmount ( ) {
76- this . mounted = false ;
96+ fetchNavigationSettings ( ) ;
97+ fetchPendingPlugins ( ) ;
98+ fetchSystemStatus ( ) ;
99+ } ) ;
100+
101+ const adminContextValue = React . useMemo (
102+ ( ) => ( {
103+ fetchSystemStatus,
104+ fetchPendingPlugins,
105+ pendingPlugins,
106+ systemStatus,
107+ } ) ,
108+ [ fetchPendingPlugins , fetchSystemStatus , pendingPlugins , systemStatus ] ,
109+ ) ;
110+
111+ // Check that the adminPages are loaded
112+ if ( ! adminPages ) {
113+ return null ;
77114 }
78115
79- fetchNavigationSettings = ( ) => {
80- getSettingsNavigation ( ) . then (
81- ( r ) => {
82- this . setState ( { adminPages : r . extensions } ) ;
83- } ,
84- ( ) => { } ,
85- ) ;
86- } ;
87-
88- fetchPendingPlugins = ( ) => {
89- getPendingPlugins ( ) . then (
90- ( pendingPlugins ) => {
91- if ( this . mounted ) {
92- this . setState ( { pendingPlugins } ) ;
93- }
94- } ,
95- ( ) => { } ,
96- ) ;
97- } ;
98-
99- fetchSystemStatus = ( ) => {
100- getSystemStatus ( ) . then (
101- ( { status } ) => {
102- if ( this . mounted ) {
103- this . setState ( { systemStatus : status } ) ;
104- if ( status === 'RESTARTING' ) {
105- this . waitRestartingDone ( ) ;
106- }
107- }
108- } ,
109- ( ) => { } ,
110- ) ;
111- } ;
112-
113- waitRestartingDone = ( ) => {
114- waitSystemUPStatus ( ) . then (
115- ( { status } ) => {
116- if ( this . mounted ) {
117- this . setState ( { systemStatus : status } ) ;
118- window . location . reload ( ) ;
119- }
120- } ,
121- ( ) => { } ,
122- ) ;
123- } ;
124-
125- render ( ) {
126- const { adminPages } = this . state ;
127-
128- // Check that the adminPages are loaded
129- if ( ! adminPages ) {
130- return null ;
131- }
116+ const adminPagesContext : AdminPagesContext = { adminPages } ;
132117
133- const { pendingPlugins, systemStatus } = this . state ;
134- const adminPagesContext : AdminPagesContext = { adminPages } ;
118+ return (
119+ < >
120+ { frontEndEngineeringEnableSidebarNavigation && (
121+ < AdministrationSidebar extensions = { adminPages } />
122+ ) }
135123
136- return (
137- < >
124+ < Layout . ContentGrid >
138125 < Helmet
139126 defer = { false }
140- titleTemplate = { this . intl . formatMessage (
127+ titleTemplate = { intl . formatMessage (
141128 { id : 'page_title.template.with_category' } ,
142129 { page : translate ( 'layout.settings' ) } ,
143130 ) }
144131 />
145132
146- { this . portalAnchor &&
147- createPortal (
133+ { ! frontEndEngineeringEnableSidebarNavigation && (
134+ < ContentHeader >
148135 < SettingsNav
149136 extensions = { adminPages }
150- fetchPendingPlugins = { this . fetchPendingPlugins }
151- fetchSystemStatus = { this . fetchSystemStatus }
137+ fetchPendingPlugins = { fetchPendingPlugins }
138+ fetchSystemStatus = { fetchSystemStatus }
152139 pendingPlugins = { pendingPlugins }
153140 systemStatus = { systemStatus }
154- /> ,
155- this . portalAnchor ,
156- ) }
141+ />
142+ </ ContentHeader >
143+ ) }
157144
158- < AdminContext . Provider
159- value = { {
160- fetchSystemStatus : this . fetchSystemStatus ,
161- fetchPendingPlugins : this . fetchPendingPlugins ,
162- pendingPlugins,
163- systemStatus,
164- } }
165- >
145+ < AdminContext . Provider value = { adminContextValue } >
166146 < Outlet context = { adminPagesContext } />
167147 </ AdminContext . Provider >
168- </ >
169- ) ;
170- }
148+ </ Layout . ContentGrid >
149+ </ >
150+ ) ;
171151}
172152
173153export default withAppStateContext ( AdminContainer ) ;
154+
155+ const ContentHeader = styled . div `
156+ grid-area: content-header;
157+ ` ;
0 commit comments