Skip to content

Commit

Permalink
Added link to admin page (#2068)
Browse files Browse the repository at this point in the history
* Added link to admin page

* Updated version

* Updated changelog
  • Loading branch information
bsekachev authored Aug 24, 2020
1 parent 1907b79 commit 18cdcd5
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 157 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [Datumaro] Dataset statistics (<https://github.com/opencv/cvat/pull/1668>)
- Ability to change label color in tasks and predefined labels (<https://github.com/opencv/cvat/pull/2014>)
- [Datumaro] Multi-dataset merge (https://github.com/opencv/cvat/pull/1695)
- Link to django admin page from UI (<https://github.com/opencv/cvat/pull/2068>)

### Changed
- Shape coordinates are rounded to 2 digits in dumped annotations (<https://github.com/opencv/cvat/pull/1970>)
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cvat-ui/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cvat-ui",
"version": "1.8.0",
"version": "1.8.1",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
4 changes: 2 additions & 2 deletions cvat-ui/src/components/cvat-app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import ModelsPageContainer from 'containers/models-page/models-page';
import AnnotationPageContainer from 'containers/annotation-page/annotation-page';
import LoginPageContainer from 'containers/login-page/login-page';
import RegisterPageContainer from 'containers/register-page/register-page';
import HeaderContainer from 'containers/header/header';
import Header from 'components/header/header';
import { customWaViewHit } from 'utils/enviroment';

import getCore from 'cvat-core-wrapper';
Expand Down Expand Up @@ -272,7 +272,7 @@ class CVATApplication extends React.PureComponent<CVATAppProps & RouteComponentP
return (
<GlobalErrorBoundary>
<Layout>
<HeaderContainer> </HeaderContainer>
<Header />
<Layout.Content style={{ height: '100%' }}>
<ShorcutsDialog />
<GlobalHotKeys keyMap={subKeyMap} handlers={handlers}>
Expand Down
204 changes: 156 additions & 48 deletions cvat-ui/src/components/header/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
// SPDX-License-Identifier: MIT

import './styles.scss';
import React, { MouseEvent } from 'react';
import { RouteComponentProps } from 'react-router';
import { withRouter } from 'react-router-dom';
import React from 'react';
import { connect } from 'react-redux';
import { useHistory } from 'react-router';
import { Row, Col } from 'antd/lib/grid';
import Layout from 'antd/lib/layout';
import Icon from 'antd/lib/icon';
Expand All @@ -15,50 +15,129 @@ import Dropdown from 'antd/lib/dropdown';
import Modal from 'antd/lib/modal';
import Text from 'antd/lib/typography/Text';

import { CVATLogo, AccountIcon } from 'icons';
import getCore from 'cvat-core-wrapper';
import consts from 'consts';

import { CVATLogo, AccountIcon } from 'icons';
import ChangePasswordDialog from 'components/change-password-modal/change-password-modal';
import { switchSettingsDialog as switchSettingsDialogAction } from 'actions/settings-actions';
import { logoutAsync, authActions } from 'actions/auth-actions';
import { SupportedPlugins, CombinedState } from 'reducers/interfaces';
import SettingsModal from './settings-modal/settings-modal';

interface HeaderContainerProps {
onLogout: () => void;
switchSettingsDialog: (show: boolean) => void;
switchChangePasswordDialog: (show: boolean) => void;
logoutFetching: boolean;
changePasswordFetching: boolean;
installedAnalytics: boolean;
serverHost: string;
username: string;
toolName: string;
serverVersion: string;
serverDescription: string;
coreVersion: string;
canvasVersion: string;
uiVersion: string;
const core = getCore();

interface Tool {
name: string;
description: string;
server: {
host: string;
version: string;
};
core: {
version: string;
};
canvas: {
version: string;
};
ui: {
version: string;
};
}

interface StateToProps {
user: any;
tool: Tool;
switchSettingsShortcut: string;
settingsDialogShown: boolean;
changePasswordDialogShown: boolean;
changePasswordFetching: boolean;
logoutFetching: boolean;
installedAnalytics: boolean;
renderChangePasswordItem: boolean;
}

type Props = HeaderContainerProps & RouteComponentProps;
interface DispatchToProps {
onLogout: () => void;
switchSettingsDialog: (show: boolean) => void;
switchChangePasswordDialog: (show: boolean) => void;
}

function mapStateToProps(state: CombinedState): StateToProps {
const {
auth: {
user,
fetching: logoutFetching,
fetching: changePasswordFetching,
showChangePasswordDialog: changePasswordDialogShown,
allowChangePassword: renderChangePasswordItem,
},
plugins: {
list,
},
about: {
server,
packageVersion,
},
shortcuts: {
normalizedKeyMap,
},
settings: {
showDialog: settingsDialogShown,
},
} = state;

return {
user,
tool: {
name: server.name as string,
description: server.description as string,
server: {
host: core.config.backendAPI.slice(0, -7),
version: server.version as string,
},
canvas: {
version: packageVersion.canvas,
},
core: {
version: packageVersion.core,
},
ui: {
version: packageVersion.ui,
},
},
switchSettingsShortcut: normalizedKeyMap.SWITCH_SETTINGS,
settingsDialogShown,
changePasswordDialogShown,
changePasswordFetching,
logoutFetching,
installedAnalytics: list[SupportedPlugins.ANALYTICS],
renderChangePasswordItem,
};
}

function mapDispatchToProps(dispatch: any): DispatchToProps {
return {
onLogout: (): void => dispatch(logoutAsync()),
switchSettingsDialog: (show: boolean): void => dispatch(switchSettingsDialogAction(show)),
switchChangePasswordDialog: (show: boolean): void => (
dispatch(authActions.switchChangePasswordDialog(show))
),
};
}

type Props = StateToProps & DispatchToProps;

function HeaderContainer(props: Props): JSX.Element {
const {
user,
tool,
installedAnalytics,
username,
toolName,
serverHost,
serverVersion,
serverDescription,
coreVersion,
canvasVersion,
uiVersion,
onLogout,
logoutFetching,
changePasswordFetching,
settingsDialogShown,
switchSettingsShortcut,
onLogout,
switchSettingsDialog,
switchChangePasswordDialog,
renderChangePasswordItem,
Expand All @@ -72,44 +151,46 @@ function HeaderContainer(props: Props): JSX.Element {
GITHUB_URL,
} = consts;

function aboutModal(): void {
const history = useHistory();

function showAboutModal(): void {
Modal.info({
title: `${toolName}`,
title: `${tool.name}`,
content: (
<div>
<p>
{`${serverDescription}`}
{`${tool.description}`}
</p>
<p>
<Text strong>
Server version:
</Text>
<Text type='secondary'>
{` ${serverVersion}`}
{` ${tool.server.version}`}
</Text>
</p>
<p>
<Text strong>
Core version:
</Text>
<Text type='secondary'>
{` ${coreVersion}`}
{` ${tool.core.version}`}
</Text>
</p>
<p>
<Text strong>
Canvas version:
</Text>
<Text type='secondary'>
{` ${canvasVersion}`}
{` ${tool.canvas.version}`}
</Text>
</p>
<p>
<Text strong>
UI version:
</Text>
<Text type='secondary'>
{` ${uiVersion}`}
{` ${tool.ui.version}`}
</Text>
</p>
<Row type='flex' justify='space-around'>
Expand All @@ -131,16 +212,27 @@ function HeaderContainer(props: Props): JSX.Element {

const menu = (
<Menu className='cvat-header-menu' mode='vertical'>
{user.isStaff && (
<Menu.Item
onClick={(): void => {
// false positive
// eslint-disable-next-line
window.open(`${tool.server.host}/admin`, '_blank');
}}
>
<Icon type='control' />
Admin page
</Menu.Item>
)}

<Menu.Item
title={`Press ${switchSettingsShortcut} to switch`}
onClick={
(): void => switchSettingsDialog(true)
}
onClick={() => switchSettingsDialog(true)}
>
<Icon type='setting' />
Settings
</Menu.Item>
<Menu.Item onClick={() => aboutModal()}>
<Menu.Item onClick={showAboutModal}>
<Icon type='info-circle' />
About
</Menu.Item>
Expand Down Expand Up @@ -178,7 +270,7 @@ function HeaderContainer(props: Props): JSX.Element {
onClick={
(event: React.MouseEvent): void => {
event.preventDefault();
props.history.push('/tasks?page=1');
history.push('/tasks?page=1');
}
}
>
Expand All @@ -192,7 +284,7 @@ function HeaderContainer(props: Props): JSX.Element {
onClick={
(event: React.MouseEvent): void => {
event.preventDefault();
props.history.push('/models');
history.push('/models');
}
}
>
Expand All @@ -203,13 +295,13 @@ function HeaderContainer(props: Props): JSX.Element {
<Button
className='cvat-header-button'
type='link'
href={`${serverHost}/analytics/app/kibana`}
href={`${tool.server.host}/analytics/app/kibana`}
onClick={
(event: React.MouseEvent): void => {
event.preventDefault();
// false positive
// eslint-disable-next-line
window.open(`${serverHost}/analytics/app/kibana`, '_blank');
window.open(`${tool.server.host}/analytics/app/kibana`, '_blank');
}
}
>
Expand Down Expand Up @@ -237,13 +329,13 @@ function HeaderContainer(props: Props): JSX.Element {
<Button
className='cvat-header-button'
type='link'
href={`${serverHost}/documentation/user_guide.html`}
href={`${tool.server.host}/documentation/user_guide.html`}
onClick={
(event: React.MouseEvent): void => {
event.preventDefault();
// false positive
// eslint-disable-next-line
window.open(`${serverHost}/documentation/user_guide.html`, '_blank')
window.open(`${tool.server.host}/documentation/user_guide.html`, '_blank')
}
}
>
Expand All @@ -254,7 +346,7 @@ function HeaderContainer(props: Props): JSX.Element {
<span>
<Icon className='cvat-header-account-icon' component={AccountIcon} />
<Text strong>
{username.length > 14 ? `${username.slice(0, 10)} ...` : username}
{user.username.length > 14 ? `${user.username.slice(0, 10)} ...` : user.username}
</Text>
<Icon className='cvat-header-menu-icon' type='caret-down' />
</span>
Expand All @@ -275,4 +367,20 @@ function HeaderContainer(props: Props): JSX.Element {
);
}

export default withRouter(HeaderContainer);
function propsAreTheSame(prevProps: Props, nextProps: Props): boolean {
let equal = true;
for (const prop in nextProps) {
if (prop in prevProps && (prevProps as any)[prop] !== (nextProps as any)[prop]) {
if (prop !== 'tool') {
equal = false;
}
}
}

return equal;
}

export default connect(
mapStateToProps,
mapDispatchToProps,
)(React.memo(HeaderContainer, propsAreTheSame));
2 changes: 1 addition & 1 deletion cvat-ui/src/components/login-page/cookie-policy-drawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ function CookieDrawer(): JSX.Element {
This site uses cookies for functionality, analytics, and advertising purposes
as described in our Cookie and Similar Technologies Notice.
To see what cookies we serve and set your preferences, please visit our
<a href='https://www.intel.com/cookies'>Cookie Consent Tool</a>
<a href='https://www.intel.com/cookies'> Cookie Consent Tool</a>
. By continuing to use our website, you agree to our use of cookies.
</Paragraph>
<Button onClick={onClose} size='large' type='primary'>
Expand Down
Loading

0 comments on commit 18cdcd5

Please sign in to comment.