src/admin/leftPanel.tsx (253 lines of code) (raw):
import * as React from 'react';
import { Resolve } from '@paperbits/react/decorators';
import { ISiteService } from '@paperbits/common/sites';
import { EventManager } from '@paperbits/common/events';
import { ViewManager } from '@paperbits/common/ui';
import { Router } from '@paperbits/common/routing';
import { Logger } from '@paperbits/common/logging';
import { initializeIcons } from '@fluentui/font-icons-mdl2';
import { CommandBarButton, Icon, IIconProps, Separator, Stack, Text, Toggle } from '@fluentui/react';
import { Pages } from './pages/pages';
import { Navigation } from './navigation/navigation';
import { Urls } from './urls/urls';
import { Popups } from './popups/popups';
import { SettingsModal } from './settings/settingsModal';
import { HelpModal } from './help/helpModal';
import { MediaModal } from './media/mediaModal';
import { CustomWidgets } from './custom-widgets/customWidgets';
import { OnboardingModal } from './onboardingModal';
import { lightTheme } from './utils/themes';
import { isRedesignEnabledSetting, mobileBreakpoint, newTheme, themeSetting } from '../constants';
initializeIcons();
const enum NavItem {
Main,
Pages,
Navigation,
URLs,
Popups,
Styles,
Media,
CustomWidgets,
Settings,
New,
Feedback,
Help
}
interface LeftPanelState {
selectedNavItem: NavItem,
isMobile: boolean,
showOnboardingModal: boolean,
isRedesignEnabled: boolean,
isNewThemeEnabled: boolean
}
const pageIcon: IIconProps = { iconName: 'Page' };
const navigationIcon: IIconProps = { iconName: 'Nav2DMapView' };
const urlIcon: IIconProps = { iconName: 'Link' };
const popupsIcon: IIconProps = { iconName: 'Documentation' };
const stylesIcon: IIconProps = { iconName: 'Color' };
const mediaIcon: IIconProps = { iconName: 'Photo2' };
const customWidgetsIcon: IIconProps = { iconName: 'Puzzle' };
const settingsIcon: IIconProps = { iconName: 'Settings' };
const whatsNewIcon: IIconProps = { iconName: 'Rocket' };
const feedbackIcon: IIconProps = { iconName: 'Megaphone' };
const helpIcon: IIconProps = { iconName: 'Help' };
const iconStyles = { root: { color: lightTheme.palette.themePrimary, fontSize: 20 } };
export class LeftPanel extends React.Component<{}, LeftPanelState> {
@Resolve('siteService')
public siteService: ISiteService;
@Resolve('eventManager')
public eventManager: EventManager;
@Resolve('viewManager')
public viewManager: ViewManager;
@Resolve('router')
public router: Router;
@Resolve('logger')
public logger: Logger;
constructor(props: any) {
super(props);
this.state = {
selectedNavItem: NavItem.Main,
isMobile: window.innerWidth < mobileBreakpoint,
showOnboardingModal: false,
isRedesignEnabled: false,
isNewThemeEnabled: false
};
}
componentDidMount(): void {
if (!localStorage.getItem('isOnboardingSeen')) this.setState({ showOnboardingModal: true });
this.loadSettings();
window.addEventListener('resize', this.checkScreenSize.bind(this));
}
componentWillUnmount() {
window.removeEventListener('resize', this.checkScreenSize.bind(this));
}
loadSettings = async (): Promise<void> => {
let redesignSetting = false;
try {
redesignSetting = await this.siteService.getSetting(isRedesignEnabledSetting);
} catch (error) {
this.logger?.trackError(error, { message: `Failed to get setting: ${isRedesignEnabledSetting} - admin panel` });
}
let themeSettingValue = '';
try {
themeSettingValue = await this.siteService.getSetting(themeSetting);
console.log(themeSettingValue);
} catch (error) {
this.logger?.trackError(error, { message: `Failed to get setting: ${themeSetting} - admin panel` });
}
this.setState({ isRedesignEnabled: !!redesignSetting });
this.setState({ isNewThemeEnabled: themeSettingValue === newTheme });
}
checkScreenSize = (): void => {
if (window.innerWidth < mobileBreakpoint) {
this.setState({ isMobile: true });
} else {
this.setState({ isMobile: false });
}
}
handleBackButtonClick = (): void => {
this.setState({ selectedNavItem: NavItem.Main });
this.viewManager.setHost({ name: 'page-host' });
}
handleOnboardingModalClose = (): void => {
this.setState({ showOnboardingModal: false });
localStorage.setItem('isOnboardingSeen', 'true');
}
renderNavItemsSwitch = (navItemValue: NavItem): JSX.Element => {
switch(navItemValue) {
case NavItem.Pages:
return <Pages onBackButtonClick={this.handleBackButtonClick.bind(this)} />;
case NavItem.Navigation:
return <Navigation onBackButtonClick={this.handleBackButtonClick.bind(this)} />;
case NavItem.URLs:
return <Urls onBackButtonClick={this.handleBackButtonClick.bind(this)} />;
case NavItem.Popups:
return <Popups onBackButtonClick={this.handleBackButtonClick.bind(this)} />;
case NavItem.CustomWidgets:
return <CustomWidgets onBackButtonClick={this.handleBackButtonClick.bind(this)} />;
default:
return (
<div className="navigation">
<CommandBarButton
iconProps={pageIcon}
text="Pages"
onClick={() => this.setState({ selectedNavItem: NavItem.Pages })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={navigationIcon}
text="Site menu"
onClick={() => this.setState({ selectedNavItem: NavItem.Navigation })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={urlIcon}
text="URLs"
onClick={() => this.setState({ selectedNavItem: NavItem.URLs })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={popupsIcon}
text="Pop-ups"
onClick={() => this.setState({ selectedNavItem: NavItem.Popups })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={mediaIcon}
text="Media"
onClick={() => this.setState({ selectedNavItem: NavItem.Media })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={stylesIcon}
text="Styles"
onClick={() => {
this.setState({ selectedNavItem: NavItem.Styles });
this.viewManager.setHost({ name: "style-guide" }, true);
if (window.innerWidth < mobileBreakpoint) document.getElementById('admin-left-panel').classList.add('hidden');
}}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={customWidgetsIcon}
text="Custom widgets"
onClick={() => this.setState({ selectedNavItem: NavItem.CustomWidgets })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={settingsIcon}
text="Settings"
onClick={() => this.setState({ selectedNavItem: NavItem.Settings })}
className="nav-item-list-button"
/>
<Separator />
<CommandBarButton
iconProps={whatsNewIcon}
text="What's new"
onClick={() => this.setState({ selectedNavItem: NavItem.New, showOnboardingModal: true })}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={feedbackIcon}
onRenderText={() =>
<Text block styles={{ root: { flexGrow: 1, margin: '0 4px' } }}>
Give feedback
<Icon iconName="OpenInNewWindow" styles={{ root: { paddingLeft: 5 } }} />
</Text>
}
onClick={() => window.open('https://github.com/Azure/api-management-developer-portal/issues', '_blank', 'noreferrer')}
className="nav-item-list-button"
/>
<CommandBarButton
iconProps={helpIcon}
text="Help"
onClick={() => this.setState({ selectedNavItem: NavItem.Help })}
className="nav-item-list-button"
/>
</div>
);
}
}
public render(): JSX.Element {
return (
<>
{this.state.showOnboardingModal && <OnboardingModal onDismiss={this.handleOnboardingModalClose.bind(this)} />}
<div className="side-panel">
<Stack horizontal className="portal-name-container">
<Stack horizontal verticalAlign="center" onClick={async () => await this.router.navigateTo('/')} styles={{ root: { cursor: 'pointer' } }}>
<Icon iconName="Home" styles={iconStyles} />
<Text className="portal-name">Home</Text>
</Stack>
<Icon
iconName="Cancel"
className="admin-side-panel-closer"
styles={iconStyles}
onClick={() => {
this.setState({ selectedNavItem: NavItem.Main });
document.getElementById('admin-left-panel').classList.add('hidden');
}}
/>
</Stack>
<div className="side-panel-content">
{ this.renderNavItemsSwitch(this.state.selectedNavItem) }
</div>
{ this.state.selectedNavItem === NavItem.Media && <MediaModal onDismiss={this.handleBackButtonClick.bind(this)} /> }
{ this.state.selectedNavItem === NavItem.Settings && <SettingsModal onDismiss={this.handleBackButtonClick.bind(this)} /> }
{ this.state.selectedNavItem === NavItem.Help && <HelpModal onDismiss={this.handleBackButtonClick.bind(this)} /> }
{!this.state.isNewThemeEnabled &&
<Toggle
label={"Preview new UI design"}
onText={"On"}
offText={"Off"}
checked={this.state.isRedesignEnabled}
onChange={async (_, checked) => {
this.setState({ isRedesignEnabled: checked });
await this.siteService.setSetting(isRedesignEnabledSetting, checked);
this.logger.trackEvent(`${checked ? 'Checked' : 'Unchecked'}: Preview new UI design`);
this.eventManager.dispatchEvent('onSaveChanges');
this.eventManager.dispatchEvent('onDataPush'); // Needed to reload the runtime part
}}
/>
}
</div>
</>
)
}
}