Files
agent/ui/src/App.jsx
T

228 lines
6.9 KiB
React

import React from 'react';
import PropTypes from 'prop-types';
import { withTranslation } from 'react-i18next';
import uuid from 'uuidv4';
import {
connect as connectWS,
disconnect as disconnectWS,
send,
} from '@giantmachines/redux-websocket';
import {
Badge,
Main,
MainBody,
Gradient,
Sidebar,
Navigation,
NavigationSection,
NavigationItem,
NavigationGroup,
Profilebar,
Icon,
} from '@kerberos-io/ui';
import { interval } from 'rxjs';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { logout } from './actions';
import config from './config';
import { getDashboardInformation } from './actions/agent';
import LanguageSelect from './components/LanguageSelect/LanguageSelect';
import logo from './header-minimal-logo-36x36.svg';
import '@kerberos-io/ui/lib/index.css';
import './App.scss';
// eslint-disable-next-line react/prefer-stateless-function
class App extends React.Component {
componentDidMount() {
const { dispatchGetDashboardInformation, dispatchConnect } = this.props;
dispatchGetDashboardInformation();
dispatchConnect();
const interval$ = interval(5000);
this.subscription = interval$.subscribe(() => {
dispatchGetDashboardInformation();
});
}
componentDidUpdate(prevProps) {
// We are connected again, lets fire the initial events.
const { connected, dispatchSend, dispatchConnect } = this.props;
const { connected: connectedPrev } = prevProps;
if (connectedPrev === false && connected === true) {
const message = {
client_id: uuid(),
message_type: 'hello',
};
dispatchSend(message);
}
// We disconnected, let's try to connect again
if (connectedPrev === true && connected === false) {
dispatchConnect();
}
}
componentWillUnmount() {
this.subscription.unsubscribe();
const message = {
client_id: uuid(),
message_type: 'goodbye',
};
const { dispatchSend, dispatchDisconnect } = this.props;
dispatchSend(message);
dispatchDisconnect();
}
getCurrentTimestamp() {
return Math.round(Date.now() / 1000);
}
render() {
const { t, connected } = this.props;
const { children, username, dashboard, dispatchLogout } = this.props;
const cloudOnline = this.getCurrentTimestamp() - dashboard.cloudOnline < 30;
return (
<div id="page-root">
<Sidebar logo={logo} title="Kerberos Agent" version="v1-beta" mobile>
<Profilebar
username={username}
email="support@kerberos.io"
userrole={t('navigation.admin')}
logout={dispatchLogout}
/>
<Navigation>
<NavigationSection title={t('navigation.management')} />
<NavigationGroup>
<NavigationItem
title={t('navigation.dashboard')}
icon="dashboard"
link="dashboard"
/>
<NavigationItem
title={t('navigation.recordings')}
icon="media"
link="media"
/>
<NavigationItem
title={t('navigation.settings')}
icon="preferences"
link="settings"
/>
</NavigationGroup>
<NavigationSection title={t('navigation.help_support')} />
<NavigationGroup>
<NavigationItem
title={t('navigation.swagger')}
icon="api"
external
link={`${config.URL}/swagger/index.html`}
/>
<NavigationItem
title={t('navigation.documentation')}
icon="book"
external
link="https://doc.kerberos.io/agent/announcement"
/>
<NavigationItem
title="Kerberos Hub"
icon="cloud"
external
link="https://app.kerberos.io"
/>
<NavigationItem
title={t('navigation.ui_library')}
icon="paint"
external
link="https://ui.kerberos.io/"
/>
<NavigationItem
title="Github"
icon="github-nav"
external
link="https://github.com/kerberos-io/agent"
/>
</NavigationGroup>
<NavigationSection title={t('navigation.layout')} />
<NavigationGroup>
<LanguageSelect />
</NavigationGroup>
<NavigationSection title="Websocket" />
<NavigationGroup>
<div className="websocket-badge">
<Badge
title={connected ? 'connected' : 'disconnected'}
status={connected ? 'success' : 'warning'}
/>
</div>
</NavigationGroup>
</Navigation>
</Sidebar>
<Main>
<Gradient />
{!cloudOnline && (
<a href="https://app.kerberos.io" target="_blank" rel="noreferrer">
<div className="cloud-not-installed">
<div>
<Icon label="cloud" />
Activate Kerberos Hub, and make your cameras and recordings
available through a secured cloud!
</div>
</div>
</a>
)}
{dashboard.offlineMode === 'true' && (
<Link to="/settings">
<div className="offline-mode">
<div>
<Icon label="info" />
Attention! Kerberos is currently running in Offline mode.
</div>
</div>
</Link>
)}
<MainBody>{children}</MainBody>
</Main>
</div>
);
}
}
const mapStateToProps = (state) => ({
username: state.authentication.username,
dashboard: state.agent.dashboard,
connected: state.wss.connected,
});
const mapDispatchToProps = (dispatch) => ({
dispatchLogout: () => dispatch(logout()),
dispatchConnect: () => {
dispatch(connectWS(config.WS_URL));
},
dispatchDisconnect: () => dispatch(disconnectWS()),
dispatchSend: (message) => dispatch(send(message)),
dispatchGetDashboardInformation: (dashboard, success, error) =>
dispatch(getDashboardInformation(dashboard, success, error)),
});
App.propTypes = {
t: PropTypes.func.isRequired,
dispatchLogout: PropTypes.func.isRequired,
dispatchConnect: PropTypes.func.isRequired,
dispatchDisconnect: PropTypes.func.isRequired,
dispatchSend: PropTypes.func.isRequired,
// eslint-disable-next-line react/forbid-prop-types
children: PropTypes.array.isRequired,
username: PropTypes.string.isRequired,
connected: PropTypes.bool.isRequired,
dashboard: PropTypes.object.isRequired,
dispatchGetDashboardInformation: PropTypes.func.isRequired,
};
export default withTranslation()(
connect(mapStateToProps, mapDispatchToProps)(App)
);