Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User interface with react and antd #755

Merged
merged 38 commits into from
Oct 14, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6ef145b
CVAT-UI: Second try
bsekachev Sep 24, 2019
7ce8038
Login page, router
bsekachev Sep 26, 2019
36338b2
Registration
bsekachev Sep 26, 2019
df50516
Changed text
bsekachev Sep 26, 2019
2b68a43
Added auto complete
bsekachev Sep 26, 2019
57b540f
Minor fixes
bsekachev Sep 27, 2019
13e0e44
Merge branch 'develop' into bs/cvat_ui
bsekachev Sep 27, 2019
50b1762
Added logout actions
bsekachev Sep 30, 2019
054f081
Added logout reducers
bsekachev Sep 30, 2019
64f19af
Added header
bsekachev Sep 30, 2019
452d230
Improved header
bsekachev Sep 30, 2019
3a5f9cc
Added empty-tasks
bsekachev Oct 1, 2019
9a08429
Tasks page initialized
bsekachev Oct 2, 2019
8f6815c
Dinamic resolution
bsekachev Oct 2, 2019
c575a2c
Dinamic resolution
bsekachev Oct 2, 2019
32ff5a1
Added preview
bsekachev Oct 3, 2019
f73a0a8
Adjusted task item
bsekachev Oct 3, 2019
c323cfc
Added menu
bsekachev Oct 3, 2019
7cba9e0
Improved error handling
bsekachev Oct 3, 2019
d40bb09
Adjusted progress color
bsekachev Oct 3, 2019
ee30f2f
Some eslint fixes
bsekachev Oct 4, 2019
ff0e3e8
Task search and pagination
bsekachev Oct 4, 2019
a653314
Merge branch 'develop' into bs/cvat_ui
bsekachev Oct 4, 2019
2ff5e2e
Pagination & filter works together
bsekachev Oct 4, 2019
af173b3
Core entrypoint
bsekachev Oct 4, 2019
f61b97f
Configurable host
bsekachev Oct 4, 2019
f5dd6c3
Prebuilt cvat-core
bsekachev Oct 4, 2019
b0e72a2
Couple of fixes
bsekachev Oct 4, 2019
c7ad2f8
Added icons
bsekachev Oct 4, 2019
b690df4
Merge branch 'develop' into bs/cvat_ui
bsekachev Oct 14, 2019
ddfe50b
Fixed preview tests
bsekachev Oct 14, 2019
fadf494
Owner/assignee name instead of id
bsekachev Oct 14, 2019
c7051fd
Task previews in redux state
bsekachev Oct 14, 2019
86d1eb1
Some class components -> functional components
bsekachev Oct 14, 2019
0e6eed5
Code refactoring
bsekachev Oct 14, 2019
40fd26f
Code refactoring
bsekachev Oct 14, 2019
21b1b48
Separated validation patterns
bsekachev Oct 14, 2019
9e64aaf
Frozen scikit-image version 0.15
bsekachev Oct 14, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Login page, router
  • Loading branch information
bsekachev committed Sep 26, 2019
commit 7ce803800061d0320f90bcda80afb0cd3c755578
1,904 changes: 1,220 additions & 684 deletions cvat-ui/package-lock.json

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions cvat-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@
"@types/react": "^16.9.2",
"@types/react-dom": "^16.9.0",
"@types/react-redux": "^7.1.2",
"@types/react-router-dom": "^4.3.5",
"@types/react-router": "^5.0.5",
"@types/react-router-dom": "^5.1.0",
"antd": "^3.23.2",
"prop-types": "^15.7.2",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-redux": "^7.1.1",
"react-router-dom": "^5.0.1",
"react-router": "^5.1.0",
"react-router-dom": "^5.1.0",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0"
}
Expand Down
63 changes: 55 additions & 8 deletions cvat-ui/src/actions/auth-actions.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,90 @@
import { AnyAction, Dispatch, ActionCreator } from 'redux';
import { ThunkAction } from 'redux-thunk';
import cvat from '../../public/cvat-core.node';
import _cvat from '../../../cvat-core/dist/cvat-core.node';

const cvat: any = _cvat;

export enum AuthActionTypes {
AUTHORIZED_ASYNC = 'AUTHORIZED_ASYNC',
AUTHORIZED_FETCHING = 'AUTHORIZED_FETCHING',
AUTHORIZED_SUCCESS = 'AUTHORIZED_SUCCESS',
AUTHORIZED_FAILED = 'AUTHORIZED_FAILED',
LOGIN_SUCCESS = 'LOGIN_SUCCESS',
LOGIN_FAILED = 'LOGIN_FAILED',
}

export function registerSuccess(user: any): AnyAction {

}

export function registerFailed(registerError: any): AnyAction {

}

export function authorizedSuccess(userInstance: any): AnyAction {
export function loginSuccess(user: any): AnyAction {
return {
type: AuthActionTypes.LOGIN_SUCCESS,
payload: {
user,
},
};
}

export function loginFailed(loginError: any): AnyAction {
return {
type: AuthActionTypes.LOGIN_FAILED,
payload: {
loginError,
},
};
}

export function authorizedSuccess(user: any): AnyAction {
return {
type: AuthActionTypes.AUTHORIZED_SUCCESS,
payload: {
user: userInstance,
user,
},
};
}

export function authorizedFailed(error: string): AnyAction {
export function authorizedFailed(authError: any): AnyAction {
return {
type: AuthActionTypes.AUTHORIZED_FAILED,
payload: {
error,
authError,
},
};
}

export function loginAsync(login: string,
password: string): ThunkAction<Promise<void>, {}, {}, AnyAction> {
return async (dispatch: ActionCreator<Dispatch>): Promise<void> => {
let user = null;
try {
await cvat.server.login(login, password);
user = await cvat.users.get({ self: true });
} catch (error) {
dispatch(loginFailed(error));
return;
}

dispatch(loginSuccess(user));
};
}

export function authorizedAsync(): ThunkAction<Promise<void>, {}, {}, AnyAction> {
return async (dispatch: ActionCreator<Dispatch>): Promise<void> => {
let result = null;
try {
result = await (cvat as any).server.authorized();
result = await cvat.server.authorized();
} catch (error) {
dispatch(authorizedFailed(error.toString()));
dispatch(authorizedFailed(error));
return;
}

if (result) {
const userInstance = await (cvat as any).users.get({ self: true });
const userInstance = await cvat.users.get({ self: true });
dispatch(authorizedSuccess(userInstance));
} else {
dispatch(authorizedSuccess(null));
Expand Down
79 changes: 79 additions & 0 deletions cvat-ui/src/components/login-form.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React from 'react';
import Text from 'antd/lib/typography/Text';
import { FormComponentProps } from 'antd/lib/form/Form';
import {
Button,
Icon,
Input,
Form,
Row,
Col
} from 'antd';

interface LoginFormProps {
onSubmit(login: string, password: string): void;
}

class LoginForm extends React.PureComponent<FormComponentProps & LoginFormProps> {
constructor(props: FormComponentProps & LoginFormProps) {
super(props);
}

private handleSubmit(e: React.FormEvent) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private handleSubmit = (event: React.FormEvent) => { ... }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not really sure it's a good idea to use such a syntax. Because it isn't a part of specification for now, as far as I know.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't worry it's a good practice in React community and is part of the ES7 specification you can enable it simply add @babel/plugin-proposal-class-properties.

And in any case, I don't recommend you use bind in render method if it not necessary, in the future, it will bad impact on performance, take a look at official documentation https://reactjs.org/docs/handling-events.html.

e.preventDefault();
this.props.form.validateFields((error, values) => {
if (!error) {
this.props.onSubmit(values.username, values.password);
}
});
}

public render() {
const { getFieldDecorator } = this.props.form;

return (
<Form onSubmit={this.handleSubmit.bind(this)} className='login-form'>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid bind use arrow function, see example above

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my comment above

<Form.Item>
{getFieldDecorator('username', {
rules: [{
required: true,
message: 'Please specify a username',
}],
})(
<Input
autoComplete='username'
prefix={<Icon type='user' style={{ color: 'rgba(0,0,0,.25)'}} />}
placeholder='Username'
/>
)}
bsekachev marked this conversation as resolved.
Show resolved Hide resolved
</Form.Item>
<Form.Item>
{getFieldDecorator('password', {
rules: [{
required: true,
message: 'Please specify a password',
}],
})(
<Input
autoComplete='current-password'
prefix={<Icon type='user' style={{ color: 'rgba(0,0,0,.25)'}} />}
placeholder='Password'
type='password'
/>
)}
</Form.Item>
<Form.Item>
<Row type='flex' justify='start' align='middle'>
<Col>
<Button type='primary' htmlType='submit' className='login-form-button'>
Sign in
</Button>
</Col>
</Row>
</Form.Item>
</Form>
);
}
}

export default Form.create<FormComponentProps & LoginFormProps>()(LoginForm);
26 changes: 17 additions & 9 deletions cvat-ui/src/containers/cvat-app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { Switch, Route, Redirect } from 'react-router';
import { BrowserRouter } from 'react-router-dom';

import { Spin } from 'antd';
import 'antd/dist/antd.css';
Expand All @@ -16,27 +17,29 @@ import LoginPage from './login-page';
import RegisterPage from './register-page';


export interface CVATProps {
export interface CVATAppProps {
auth: AuthState;
}

export interface CVATActProps {
export interface CVATAppActions {
verifyAuthorized: () => void;
}

function mapStateToProps(state: any): CVATProps {
function mapStateToProps(state: any): CVATAppProps {
return {
auth: state.auth,
};
}

function mapDispatchToProps(dispatch: any): CVATActProps {
function mapDispatchToProps(dispatch: any): CVATAppActions {
return {
verifyAuthorized: (): void => dispatch(authorizedAsync())
};
}

class CVATApplication extends React.PureComponent<CVATProps & CVATActProps> {
class CVATApplication extends React.PureComponent<
CVATAppProps &
CVATAppActions> {
constructor(props: any) {
super(props);
}
Expand All @@ -52,18 +55,23 @@ class CVATApplication extends React.PureComponent<CVATProps & CVATActProps> {
return (
<BrowserRouter>
<Switch>
<Route exact path='/auth/register' component={RegisterPage}/>
<Route exact path='/auth/login' component={LoginPage}/>
<Route exact path='/tasks' component={TasksPage}/>
<Route path='/tasks/create' component={CreateTaskPage}/>
<Route path='/tasks/:number' component={TaskPage}/>
<Route path='/tasks/:number/jobs/:number' component={AnnotationPage}/>
<Redirect to='/tasks'/>
</Switch>
</BrowserRouter>
);
} else {
return (
<LoginPage />
<BrowserRouter>
<Switch>
<Route exact path='/auth/register' component={RegisterPage}/>
<Route exact path='/auth/login' component={LoginPage}/>
<Redirect to='/auth/login'/>
</Switch>
</BrowserRouter>
);
}
} else {
Expand Down
83 changes: 72 additions & 11 deletions cvat-ui/src/containers/login-page.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,84 @@
import React from 'react';
import { Button, Icon, Input, Form, Col, Row } from 'antd';
import { connect } from 'react-redux';
import { RouteComponentProps } from 'react-router';
import { Redirect, Link, withRouter } from 'react-router-dom';

import Title from 'antd/lib/typography/Title';
import Text from 'antd/lib/typography/Text';
import {
Col,
Row
} from 'antd';

import LoginForm from '../components/login-form';

import { loginAsync } from '../actions/auth-actions';
import { AuthState } from '../reducers/auth-reducer';

interface LoginPageProps {
auth: AuthState;
}

interface LoginPageActions {
login(login: string, password: string): void;
}

export default class LoginPage extends React.PureComponent {
function mapStateToProps(state: any): LoginPageProps {
return {
auth: state.auth,
};
}

function mapDispatchToProps(dispatch: any): LoginPageActions {
return {
login: (login: string, password: string) => dispatch(loginAsync(login, password)),
}
}

class LoginPage extends React.PureComponent<
LoginPageProps &
LoginPageActions &
RouteComponentProps> {
constructor(props: any) {
super(props);
}

public render() {
const { loginError } = this.props.auth;
const sizes = {
xs: { span: 14 },
sm: { span: 14 },
md: { span: 10 },
lg: { span: 4 },
xl: { span: 4 },
}
return (
<div>
<Row type="flex" justify="center" align="middle">
<Col xs={{span: 14}} sm={{span: 12}} md={{span: 10}} lg={{span: 8}} xl={{span: 6}}>
<Form>
<Title>Login</Title>
</Form>
</Col>
</Row>
</div>
<Row type='flex' justify='center' align='middle'>
<Col {...sizes}>
<Redirect to='/auth/login'/>
<Title level={2}> Login </Title>
<LoginForm onSubmit={this.props.login}/>
{ loginError &&
<Row>
<Col>
<Text type="danger"> { loginError.message } </Text>
</Col>
</Row>
}
<Row type='flex' justify='start' align='top'>
<Col>
<Text strong>
New to CVAT? Create <Link to="/auth/register">an account</Link>
</Text>
</Col>
</Row>
</Col>
</Row>
);
}
}

export default withRouter(connect(
mapStateToProps,
mapDispatchToProps,
)(LoginPage));
4 changes: 3 additions & 1 deletion cvat-ui/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
</head>

<body>
<div id="root" style="width: 100%; height: 100%;">
<div id="root" style="width: 100%; height: 100%; display: grid;">

</div>

<script src="/cvat-ui.min.js" type="text/javascript"></script>
</body>
</html>
8 changes: 2 additions & 6 deletions cvat-ui/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';

import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';

import rootReducer from './reducers/root-reducer';
import CVATApplication from './containers/cvat-app';
import createCVATStore from './store';

const middlewares = [thunk];
const cvatStore = createStore(rootReducer, applyMiddleware(...middlewares))
const cvatStore = createCVATStore();

ReactDOM.render(
(
Expand Down
Loading