From 18cdcd5daae16294a353139bdfe2d3e9304b14b2 Mon Sep 17 00:00:00 2001 From: Boris Sekachev Date: Mon, 24 Aug 2020 13:46:50 +0300 Subject: [PATCH] Added link to admin page (#2068) * Added link to admin page * Updated version * Updated changelog --- CHANGELOG.md | 1 + cvat-ui/package-lock.json | 2 +- cvat-ui/package.json | 2 +- cvat-ui/src/components/cvat-app.tsx | 4 +- cvat-ui/src/components/header/header.tsx | 204 +++++++++++++----- .../login-page/cookie-policy-drawer.tsx | 2 +- .../register-page/register-form.tsx | 14 +- cvat-ui/src/containers/header/header.tsx | 97 --------- 8 files changed, 169 insertions(+), 157 deletions(-) delete mode 100644 cvat-ui/src/containers/header/header.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 47964aca..3c2cf34b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [Datumaro] Dataset statistics () - Ability to change label color in tasks and predefined labels () - [Datumaro] Multi-dataset merge (https://github.com/opencv/cvat/pull/1695) +- Link to django admin page from UI () ### Changed - Shape coordinates are rounded to 2 digits in dumped annotations () diff --git a/cvat-ui/package-lock.json b/cvat-ui/package-lock.json index f8f63da4..f5f4b8dc 100644 --- a/cvat-ui/package-lock.json +++ b/cvat-ui/package-lock.json @@ -1,6 +1,6 @@ { "name": "cvat-ui", - "version": "1.8.0", + "version": "1.8.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/cvat-ui/package.json b/cvat-ui/package.json index d47c1da6..6c8da4ea 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -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": { diff --git a/cvat-ui/src/components/cvat-app.tsx b/cvat-ui/src/components/cvat-app.tsx index 50d7ce04..517cf192 100644 --- a/cvat-ui/src/components/cvat-app.tsx +++ b/cvat-ui/src/components/cvat-app.tsx @@ -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'; @@ -272,7 +272,7 @@ class CVATApplication extends React.PureComponent - +
diff --git a/cvat-ui/src/components/header/header.tsx b/cvat-ui/src/components/header/header.tsx index 87db4c51..379e7c70 100644 --- a/cvat-ui/src/components/header/header.tsx +++ b/cvat-ui/src/components/header/header.tsx @@ -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'; @@ -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, @@ -72,20 +151,22 @@ 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: (

- {`${serverDescription}`} + {`${tool.description}`}

Server version: - {` ${serverVersion}`} + {` ${tool.server.version}`}

@@ -93,7 +174,7 @@ function HeaderContainer(props: Props): JSX.Element { Core version: - {` ${coreVersion}`} + {` ${tool.core.version}`}

@@ -101,7 +182,7 @@ function HeaderContainer(props: Props): JSX.Element { Canvas version: - {` ${canvasVersion}`} + {` ${tool.canvas.version}`}

@@ -109,7 +190,7 @@ function HeaderContainer(props: Props): JSX.Element { UI version: - {` ${uiVersion}`} + {` ${tool.ui.version}`}

@@ -131,16 +212,27 @@ function HeaderContainer(props: Props): JSX.Element { const menu = ( + {user.isStaff && ( + { + // false positive + // eslint-disable-next-line + window.open(`${tool.server.host}/admin`, '_blank'); + }} + > + + Admin page + + )} + switchSettingsDialog(true) - } + onClick={() => switchSettingsDialog(true)} > Settings - aboutModal()}> + About @@ -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'); } } > @@ -192,7 +284,7 @@ function HeaderContainer(props: Props): JSX.Element { onClick={ (event: React.MouseEvent): void => { event.preventDefault(); - props.history.push('/models'); + history.push('/models'); } } > @@ -203,13 +295,13 @@ function HeaderContainer(props: Props): JSX.Element {