-
Reinder Kraaij authoredReinder Kraaij authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
App.js 11.40 KiB
import { Component } from 'react';
import { Redirect, BrowserRouter as Router } from 'react-router-dom';
import classNames from 'classnames';
import AppTopbar from './layout/components/AppTopbar';
import AppMenu from './layout/components/AppMenu';
import { RoutedContent } from './routes';
import AppBreadcrumb from "./layout/components/AppBreadcrumb";
import handleResponse from "./response.handler"
import 'primeicons/primeicons.css';
import 'primereact/resources/primereact.css';
import 'primereact/resources/themes/nova/theme.css';
import { withFaroProfiler ,faro} from '@grafana/faro-react';
import './layout/layout.scss';
import 'primeflex/primeflex.css';
import './App.scss';
import './App.css';
import Auth from './authenticate/auth';
import pubsub from './utils/pubSub';
import { CustomDialog } from './layout/components/CustomDialog';
import AuthStore from './authenticate/auth.store';
import { Provider } from "react-redux";
import AuthComponent from './components/AuthComponent';
const { publish, subscribe } = pubsub();
export {
publish,
subscribe
};
class App extends Component {
constructor() {
super();
this.state = {
layoutMode: 'static',
currentMenu: '',
currentPath: '/',
PageTitle: '',
isBreadCrumbVisible: false,
isDateTimeVisible: true,
staticMenuInactive: localStorage.getItem('staticMenuInactive') === 'true',
overlayMenuActive: localStorage.getItem('overlayMenuActive') === 'true',
mobileMenuActive: localStorage.getItem('mobileMenuActive') === 'true',
authenticated: true,
findObjectPlaceholder: 'Sub Task',
redirect: window.location?.pathname === '/' ? '/su/timelineview/week' : window.location?.pathname,
isLogin: true
};
this.onToggleMenu = this.onToggleMenu.bind(this);
this.onMenuItemClick = this.onMenuItemClick.bind(this);
this.setPageTitle = this.setPageTitle.bind(this);
this.logout = this.logout.bind(this);
this.validateAndLogout = this.validateAndLogout.bind(this);
this.setSearchField = this.setSearchField.bind(this);
this.toggleEditToggle = this.toggleEditToggle.bind(this);
this.ReportSubMenu = [
{ label: 'Failure ', icon: 'pi pi-fw pi-chart-bar', to: '/reports/failure', section: 'reports', isBreadCrumbVisible: false, isDateTimeVisible: false },
{ label: 'Cycle ', icon: 'pi pi-fw pi-history', to: '/reports/cycle', section: 'reports', isBreadCrumbVisible: false, isDateTimeVisible: false },
{ label: 'Project ', icon: 'pi pi-fw pi-table', to: '/reports/project', section: 'reports', isBreadCrumbVisible: false, isDateTimeVisible: false }
]
this.menu = [
{ label: 'Calendar', icon: 'pi pi-fw pi-calendar-times', to: '/su/timelineview/week', section: 'su/timelineview/week', isBreadCrumbVisible: false, isDateTimeVisible: true },
{ label: 'Cycle', icon: 'pi pi-fw pi-spinner', to: '/cycle', section: 'cycle', isBreadCrumbVisible: true, isDateTimeVisible: false },
{ label: 'Daily Schedule', icon: 'pi pi-fw pi-sun', to: '/constraint/view', section: 'system', isBreadCrumbVisible: false, isDateTimeVisible: true },
{ label: 'Project', icon: 'pi pi-fw pi-compass', to: '/project', section: 'project', isBreadCrumbVisible: true, isDateTimeVisible: false },
{ label: 'Reservations', icon: 'pi pi-fw pi-book', to: '/reservation/list', section: 'system', isBreadCrumbVisible: false, isDateTimeVisible: true },
{ label: 'Reports', icon: 'pi pi-fw pi-chart-bar', to: '/reports/failure', section: 'reports', isBreadCrumbVisible: false, isDateTimeVisible: false, items: this.ReportSubMenu },
{ label: 'Scheduling Units', icon: 'pi pi-fw pi-calendar', to: '/schedulingunit', section: 'schedulingunit', isBreadCrumbVisible: true, isDateTimeVisible: false },
{ label: 'Stations', icon: 'pi pi-fw pi-wifi pi-rotate', to: '/station/list', section: 'system', isBreadCrumbVisible: false, isDateTimeVisible: true },
{ label: 'System Events', icon: 'pi pi-fw pi-bolt', to: '/systemevent/list', section: 'system', isBreadCrumbVisible: false, isDateTimeVisible: true },
{ label: 'Tasks', icon: 'pi pi-fw pi-check-square', to: '/task', isBreadCrumbVisible: true, isDateTimeVisible: false },
{ label: 'Workflow', icon: 'pi pi-fw pi-sitemap', to: '/su/workflow', section: 'workflow', isBreadCrumbVisible: true, isDateTimeVisible: false },
];
}
onToggleMenu(event) {
this.menuClick = true;
if (this.isDesktop()) {
this.setState(prevState => ({
staticMenuInactive: !prevState.staticMenuInactive
}), () => {
localStorage.setItem('staticMenuInactive', !this.state.staticMenuInactive);
});
} else {
this.setState(prevState => ({
mobileMenuActive: !prevState.mobileMenuActive
}), () => {
localStorage.setItem('mobileMenuActive', this.state.mobileMenuActive);
});
}
event.preventDefault();
}
onMenuItemClick(event) {
faro?.api?.pushEvent('App onMenuItemClick');
this.setState({ currentMenu: event.item.label, currentPath: event.item.path, isBreadCrumbVisible: event.item.isBreadCrumbVisible, isDateTimeVisible: event.item.isDateTimeVisible });
}
isDesktop() {
return window.innerWidth > 1024;
}
setPageTitle(PageTitle) {
if (PageTitle !== this.state.PageTitle) {
this.setState({ PageTitle })
}
}
/**
* Logout and redirect to login page.
*/
logout() {
Auth.logout();
this.setState({ redirect: "/login", isLogin: false });
faro?.api?.pushEvent('Logout');
}
/**
* Get confirmation if any of the page has unsaved data and then logout.
* @returns
*/
validateAndLogout() {
if (this.state.isEditDirty) {
this.toggleDirtyDialog(this.logout);
} else {
this.logout();
}
}
toggleEditToggle() {
this.setState(prevState => ({
showEditDialog: !prevState.showEditDialog
}));
}
componentDidMount() {
subscribe('edit-dirty', (flag) => {
this.setState({ isEditDirty: flag }, () => {
if (flag) {
window.addEventListener("beforeunload", reloadDirty);
window.history.pushState(null, document.title, window.location.href);
window.addEventListener('popstate', this.onBackButtonEvent);
} else {
window.removeEventListener("beforeunload", reloadDirty);
}
});
});
let reloadDirty = function (e) {
let confirmationMessage = "\\o/";
(e).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage;
};
}
componentDidUpdate() {
if (window.location?.pathname === '/') {
this.setState({ redirect: '/su/timelineview/week', isBreadCrumbVisible: false, isDateTimeVisible: true })
}
}
onBackButtonEvent = (e) => {
e.preventDefault();
if (this.state.isEditDirty) {
const leavePage = window.confirm("Do you want to discard your changes? Your changes may not be saved.");
if (leavePage) {
this.setState({ isEditDirty: false });
window.history.back();
} else {
window.history.pushState(null, document.title, window.location.href);
}
}
}
close = () => {
this.setState({ showDirtyDialog: false });
}
/**
* Cancel edit and redirect to Cycle View page
*/
cancelEdit = () => {
this.setState({ isEditDirty: false, showDirtyDialog: false });
this.state.toPathCallback();
}
toggleDirtyDialog = (callback) => {
this.setState({ showDirtyDialog: true, toPathCallback: callback });
}
onBreadcrumbClick = (callback) => {
if (this.state.isEditDirty) {
this.toggleDirtyDialog(callback);
return;
}
callback();
}
/**
* Set search param
* @param {*} key
* @param {*} value
*/
setSearchField(key, value) {
this.setState({
objectType: key,
findObjectId: value,
redirect: "/find/object/" + key + "/" + value
});
}
render() {
const wrapperClass = classNames('layout-wrapper', {
'layout-static': this.state.layoutMode === 'static',
'layout-static-sidebar-inactive': this.state.staticMenuInactive ,
'layout-mobile-sidebar-active': this.state.mobileMenuActive
});
return (
<div className="App">
<Provider store={AuthStore}>
<div className={wrapperClass}>
{/* Load main routes and application only if the application is authenticated */}
{this.state.redirect &&
<AuthComponent>
<AppTopbar
onToggleMenu={this.onToggleMenu}
isLoggedIn={this.state.authenticated}
onLogout={this.validateAndLogout}
setSearchField={this.setSearchField}
isDateTimeVisible={this.state.isDateTimeVisible}
/>
<Router basename={this.state.currentPath}>
<AppMenu model={this.menu} toggleDirtyDialog={this.toggleDirtyDialog} isEditDirty={this.state.isEditDirty} onMenuItemClick={this.onMenuItemClick} active={this.state.menuActive} />
<div className="layout-main">
{(this.state.redirect || this.state.redirect === "/login") &&
<Redirect to={{ pathname: this.state.redirect === "/login" ? "/su/timelineview/week" : this.state.redirect, state: { userrole: this.state.userrole } }} />}
{(this.state.isBreadCrumbVisible) &&
<AppBreadcrumb setPageTitle={this.setPageTitle} section={this.state.currentMenu} onBreadcrumbClick={this.onBreadcrumbClick} />
}
<RoutedContent />
</div>
</Router>
</AuthComponent>
}
<CustomDialog type="confirmation" visible={this.state.showDirtyDialog} width="40vw"
header={'Confirmation'} message={'Do you want to discard your changes? Your changes may not be saved.'}
content={''} onClose={this.close}
actions={[{ id: "yes", title: 'Discard', callback: this.cancelEdit, className: 'act-btn-dispose' },
{ id: "no", title: 'Cancel', className: 'act-btn-cancel', callback: this.close }]}>
</CustomDialog>
</div>
</Provider>
</div>
);
}
}
export default handleResponse(withFaroProfiler(App));