From efa47a3aa369dec9ecb7dea60f5aa83c22ee3639 Mon Sep 17 00:00:00 2001 From: Artyom Zankevich Date: Wed, 31 Jul 2019 12:44:52 +0300 Subject: [PATCH] [NEW-UI] Delete task and pagination edge-cases (#599) --- cvat-ui/package.json | 2 + cvat-ui/src/actions/auth.actions.ts | 4 +- cvat-ui/src/actions/tasks.actions.ts | 28 ++- cvat-ui/src/components/app/app.test.tsx | 2 + cvat-ui/src/components/app/app.tsx | 47 +++-- .../content/dashboard-content.scss | 0 .../content/dashboard-content.test.tsx | 2 + .../content/dashboard-content.tsx | 6 +- .../dashboard-page.scss} | 0 .../dashboard-page.test.tsx} | 4 +- .../dashboard-page.tsx} | 23 +-- .../footer/dashboard-footer.scss | 0 .../footer/dashboard-footer.test.tsx | 2 + .../footer/dashboard-footer.tsx | 0 .../header/dashboard-header.scss | 0 .../header/dashboard-header.test.tsx | 2 + .../header/dashboard-header.tsx | 0 .../login.scss => login-page/login-page.scss} | 0 .../login-page.test.tsx} | 4 +- .../login.tsx => login-page/login-page.tsx} | 14 +- .../page-not-found.scss} | 0 .../page-not-found.test.tsx} | 4 +- .../page-not-found.tsx} | 6 +- .../register-page/register-page.scss | 10 + .../register-page/register-page.test.tsx | 11 + .../register-page/register-page.tsx | 188 ++++++++++++++++++ cvat-ui/src/index.tsx | 6 +- cvat-ui/src/store.ts | 15 +- cvat-ui/src/utils/.gitkeep | 0 cvat-ui/src/utils/tasks-filter-dto.ts | 13 ++ 30 files changed, 340 insertions(+), 53 deletions(-) rename cvat-ui/src/components/{dashboard => dashboard-page}/content/dashboard-content.scss (100%) rename cvat-ui/src/components/{dashboard => dashboard-page}/content/dashboard-content.test.tsx (99%) rename cvat-ui/src/components/{dashboard => dashboard-page}/content/dashboard-content.tsx (95%) rename cvat-ui/src/components/{dashboard/dashboard.scss => dashboard-page/dashboard-page.scss} (100%) rename cvat-ui/src/components/{dashboard/dashboard.test.tsx => dashboard-page/dashboard-page.test.tsx} (83%) rename cvat-ui/src/components/{dashboard/dashboard.tsx => dashboard-page/dashboard-page.tsx} (73%) rename cvat-ui/src/components/{dashboard => dashboard-page}/footer/dashboard-footer.scss (100%) rename cvat-ui/src/components/{dashboard => dashboard-page}/footer/dashboard-footer.test.tsx (99%) rename cvat-ui/src/components/{dashboard => dashboard-page}/footer/dashboard-footer.tsx (100%) rename cvat-ui/src/components/{dashboard => dashboard-page}/header/dashboard-header.scss (100%) rename cvat-ui/src/components/{dashboard => dashboard-page}/header/dashboard-header.test.tsx (99%) rename cvat-ui/src/components/{dashboard => dashboard-page}/header/dashboard-header.tsx (100%) rename cvat-ui/src/components/{login/login.scss => login-page/login-page.scss} (100%) rename cvat-ui/src/components/{login/login.test.tsx => login-page/login-page.test.tsx} (86%) rename cvat-ui/src/components/{login/login.tsx => login-page/login-page.tsx} (90%) rename cvat-ui/src/components/{not-found/not-found.scss => page-not-found/page-not-found.scss} (100%) rename cvat-ui/src/components/{not-found/not-found.test.tsx => page-not-found/page-not-found.test.tsx} (84%) rename cvat-ui/src/components/{not-found/not-found.tsx => page-not-found/page-not-found.tsx} (72%) create mode 100644 cvat-ui/src/components/register-page/register-page.scss create mode 100644 cvat-ui/src/components/register-page/register-page.test.tsx create mode 100644 cvat-ui/src/components/register-page/register-page.tsx delete mode 100644 cvat-ui/src/utils/.gitkeep create mode 100644 cvat-ui/src/utils/tasks-filter-dto.ts diff --git a/cvat-ui/package.json b/cvat-ui/package.json index 482e32d3..e198d615 100644 --- a/cvat-ui/package.json +++ b/cvat-ui/package.json @@ -10,6 +10,7 @@ "@types/react-dom": "16.8.4", "@types/react-redux": "^7.1.1", "@types/react-router-dom": "^4.3.4", + "@types/redux-logger": "^3.0.7", "antd": "^3.19.1", "babel-plugin-import": "^1.11.2", "customize-cra": "^0.2.12", @@ -24,6 +25,7 @@ "react-router-dom": "^5.0.1", "react-scripts": "3.0.1", "redux": "^4.0.3", + "redux-logger": "^3.0.6", "redux-thunk": "^2.3.0", "source-map-explorer": "^1.8.0", "typescript": "3.4.5" diff --git a/cvat-ui/src/actions/auth.actions.ts b/cvat-ui/src/actions/auth.actions.ts index 864c4d4b..64fe491d 100644 --- a/cvat-ui/src/actions/auth.actions.ts +++ b/cvat-ui/src/actions/auth.actions.ts @@ -17,13 +17,15 @@ export const loginError = (error = {}) => (dispatch: any) => { }); } -export const loginAsync = (username: string, password: string) => { +export const loginAsync = (username: string, password: string, history: any) => { return (dispatch: any) => { dispatch(login()); return (window as any).cvat.server.login(username, password).then( (authenticated: any) => { + localStorage.setItem('session', 'true'); dispatch(loginSuccess()); + history.push(history.location.state ? history.location.state.from : '/dashboard'); }, (error: any) => { dispatch(loginError(error)); diff --git a/cvat-ui/src/actions/tasks.actions.ts b/cvat-ui/src/actions/tasks.actions.ts index 481176b4..91a072ae 100644 --- a/cvat-ui/src/actions/tasks.actions.ts +++ b/cvat-ui/src/actions/tasks.actions.ts @@ -1,3 +1,8 @@ +import queryString from 'query-string'; + +import setQueryObject from '../utils/tasks-filter-dto' + + export const getTasks = () => (dispatch: any, getState: any) => { dispatch({ type: 'GET_TASKS', @@ -52,14 +57,31 @@ export const getTasksAsync = (queryObject = {}) => { }; } -export const deleteTaskAsync = (task: any) => { - return (dispatch: any) => { +export const deleteTaskAsync = (task: any, history: any) => { + return (dispatch: any, getState: any) => { dispatch(deleteTask()); return task.delete().then( (deleted: any) => { dispatch(deleteTaskSuccess()); - dispatch(getTasksAsync()); + + const state = getState(); + + const queryObject = { + page: state.tasksFilter.currentPage, + search: state.tasksFilter.searchQuery, + } + + if (state.tasks.tasks.length === 1 && state.tasks.tasksCount !== 1) { + queryObject.page = queryObject.page - 1; + + history.push({ search: queryString.stringify(queryObject) }); + } else if (state.tasks.tasksCount === 1) { + dispatch(getTasksAsync()); + } else { + const query = setQueryObject(queryObject); + dispatch(getTasksAsync(query)); + } }, (error: any) => { dispatch(deleteTaskError(error)); diff --git a/cvat-ui/src/components/app/app.test.tsx b/cvat-ui/src/components/app/app.test.tsx index e9957993..21ab2b40 100644 --- a/cvat-ui/src/components/app/app.test.tsx +++ b/cvat-ui/src/components/app/app.test.tsx @@ -1,7 +1,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; + import App from './app'; + it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); diff --git a/cvat-ui/src/components/app/app.tsx b/cvat-ui/src/components/app/app.tsx index 07601089..a0cb97c6 100644 --- a/cvat-ui/src/components/app/app.tsx +++ b/cvat-ui/src/components/app/app.tsx @@ -2,34 +2,47 @@ import React, { PureComponent } from 'react'; import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'; import { connect } from 'react-redux'; -import { loginAsync } from '../../actions/auth.actions'; -import Dashboard from '../dashboard/dashboard'; -import Login from '../login/login'; -import NotFound from '../not-found/not-found'; +import DashboardPage from '../dashboard-page/dashboard-page'; +import LoginPage from '../login-page/login-page'; +import RegisterPage from '../register-page/register-page'; +import PageNotFound from '../page-not-found/page-not-found'; import './app.scss'; -class App extends PureComponent { - componentDidMount() { - // TODO: remove when proper login flow (with router) will be implemented - this.props.dispatch( - loginAsync( - process.env.REACT_APP_LOGIN as string, - process.env.REACT_APP_PASSWORD as string, - ), - ); - } +const ProtectedRoute = ({ component: Component, ...rest }: any) => { + return ( + { + return localStorage.getItem('session') ? ( + + ) : ( + + ); + } } + /> + ); +}; +class App extends PureComponent { render() { return( - - - + + + + ); diff --git a/cvat-ui/src/components/dashboard/content/dashboard-content.scss b/cvat-ui/src/components/dashboard-page/content/dashboard-content.scss similarity index 100% rename from cvat-ui/src/components/dashboard/content/dashboard-content.scss rename to cvat-ui/src/components/dashboard-page/content/dashboard-content.scss diff --git a/cvat-ui/src/components/dashboard/content/dashboard-content.test.tsx b/cvat-ui/src/components/dashboard-page/content/dashboard-content.test.tsx similarity index 99% rename from cvat-ui/src/components/dashboard/content/dashboard-content.test.tsx rename to cvat-ui/src/components/dashboard-page/content/dashboard-content.test.tsx index 37a04805..0aa28ae2 100644 --- a/cvat-ui/src/components/dashboard/content/dashboard-content.test.tsx +++ b/cvat-ui/src/components/dashboard-page/content/dashboard-content.test.tsx @@ -1,7 +1,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; + import DashboardContent from './dashboard-content'; + it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); diff --git a/cvat-ui/src/components/dashboard/content/dashboard-content.tsx b/cvat-ui/src/components/dashboard-page/content/dashboard-content.tsx similarity index 95% rename from cvat-ui/src/components/dashboard/content/dashboard-content.tsx rename to cvat-ui/src/components/dashboard-page/content/dashboard-content.tsx index 8581c30b..ef95db75 100644 --- a/cvat-ui/src/components/dashboard/content/dashboard-content.tsx +++ b/cvat-ui/src/components/dashboard-page/content/dashboard-content.tsx @@ -1,5 +1,7 @@ import React, { Component } from 'react'; +import { withRouter } from 'react-router-dom'; + import { connect } from 'react-redux'; import { deleteTaskAsync } from '../../../actions/tasks.actions'; @@ -120,7 +122,7 @@ class DashboardContent extends Component { okType: 'danger', centered: true, onOk() { - return self.props.dispatch(deleteTaskAsync(task)); + return self.props.dispatch(deleteTaskAsync(task, self.props.history)); }, cancelText: 'No', onCancel() { @@ -142,4 +144,4 @@ const mapStateToProps = (state: any) => { return state.tasks; }; -export default connect(mapStateToProps)(DashboardContent); +export default withRouter(connect(mapStateToProps)(DashboardContent) as any); diff --git a/cvat-ui/src/components/dashboard/dashboard.scss b/cvat-ui/src/components/dashboard-page/dashboard-page.scss similarity index 100% rename from cvat-ui/src/components/dashboard/dashboard.scss rename to cvat-ui/src/components/dashboard-page/dashboard-page.scss diff --git a/cvat-ui/src/components/dashboard/dashboard.test.tsx b/cvat-ui/src/components/dashboard-page/dashboard-page.test.tsx similarity index 83% rename from cvat-ui/src/components/dashboard/dashboard.test.tsx rename to cvat-ui/src/components/dashboard-page/dashboard-page.test.tsx index 956dcb5f..4a12c570 100644 --- a/cvat-ui/src/components/dashboard/dashboard.test.tsx +++ b/cvat-ui/src/components/dashboard-page/dashboard-page.test.tsx @@ -1,6 +1,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Dashboard from './dashboard'; + +import Dashboard from './dashboard-page'; + it('renders without crashing', () => { const div = document.createElement('div'); diff --git a/cvat-ui/src/components/dashboard/dashboard.tsx b/cvat-ui/src/components/dashboard-page/dashboard-page.tsx similarity index 73% rename from cvat-ui/src/components/dashboard/dashboard.tsx rename to cvat-ui/src/components/dashboard-page/dashboard-page.tsx index d7a28adf..15429df1 100644 --- a/cvat-ui/src/components/dashboard/dashboard.tsx +++ b/cvat-ui/src/components/dashboard-page/dashboard-page.tsx @@ -3,6 +3,8 @@ import { Location, Action } from 'history'; import * as queryString from 'query-string'; +import setQueryObject from '../../utils/tasks-filter-dto' + import { connect } from 'react-redux'; import { getTasksAsync } from '../../actions/tasks.actions'; import { filterTasks } from '../../actions/tasks-filter.actions'; @@ -13,7 +15,8 @@ import DashboardHeader from './header/dashboard-header'; import DashboardContent from './content/dashboard-content'; import DashboardFooter from './footer/dashboard-footer'; -import './dashboard.scss'; +import './dashboard-page.scss'; + class Dashboard extends PureComponent { componentDidMount() { @@ -21,7 +24,7 @@ class Dashboard extends PureComponent { this.props.history.listen((location: Location, action: Action) => { this.loadTasks(location.search); - }) + }); } render() { @@ -36,25 +39,11 @@ class Dashboard extends PureComponent { private loadTasks = (params: any) => { const query = queryString.parse(params); - const queryObject = this.setQueryObject(query); + const queryObject = setQueryObject(query); this.props.dispatch(filterTasks(queryObject)); this.props.dispatch(getTasksAsync(queryObject)); } - - private setQueryObject = (params: { search?: string, page?: string }): { search?: string, page?: number } => { - const queryObject: { search?: string, page?: number } = {}; - - if (params['search']) { - queryObject.search = params.search.toString(); - } - - if (params['page']) { - queryObject.page = parseInt(params.page); - } - - return queryObject; - } } const mapStateToProps = (state: any) => { diff --git a/cvat-ui/src/components/dashboard/footer/dashboard-footer.scss b/cvat-ui/src/components/dashboard-page/footer/dashboard-footer.scss similarity index 100% rename from cvat-ui/src/components/dashboard/footer/dashboard-footer.scss rename to cvat-ui/src/components/dashboard-page/footer/dashboard-footer.scss diff --git a/cvat-ui/src/components/dashboard/footer/dashboard-footer.test.tsx b/cvat-ui/src/components/dashboard-page/footer/dashboard-footer.test.tsx similarity index 99% rename from cvat-ui/src/components/dashboard/footer/dashboard-footer.test.tsx rename to cvat-ui/src/components/dashboard-page/footer/dashboard-footer.test.tsx index b52f6d91..9ab621e1 100644 --- a/cvat-ui/src/components/dashboard/footer/dashboard-footer.test.tsx +++ b/cvat-ui/src/components/dashboard-page/footer/dashboard-footer.test.tsx @@ -1,7 +1,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; + import DashboardFooter from './dashboard-footer'; + it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); diff --git a/cvat-ui/src/components/dashboard/footer/dashboard-footer.tsx b/cvat-ui/src/components/dashboard-page/footer/dashboard-footer.tsx similarity index 100% rename from cvat-ui/src/components/dashboard/footer/dashboard-footer.tsx rename to cvat-ui/src/components/dashboard-page/footer/dashboard-footer.tsx diff --git a/cvat-ui/src/components/dashboard/header/dashboard-header.scss b/cvat-ui/src/components/dashboard-page/header/dashboard-header.scss similarity index 100% rename from cvat-ui/src/components/dashboard/header/dashboard-header.scss rename to cvat-ui/src/components/dashboard-page/header/dashboard-header.scss diff --git a/cvat-ui/src/components/dashboard/header/dashboard-header.test.tsx b/cvat-ui/src/components/dashboard-page/header/dashboard-header.test.tsx similarity index 99% rename from cvat-ui/src/components/dashboard/header/dashboard-header.test.tsx rename to cvat-ui/src/components/dashboard-page/header/dashboard-header.test.tsx index 417876ec..6ca75cf6 100644 --- a/cvat-ui/src/components/dashboard/header/dashboard-header.test.tsx +++ b/cvat-ui/src/components/dashboard-page/header/dashboard-header.test.tsx @@ -1,7 +1,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; + import DashboardHeader from './dashboard-header'; + it('renders without crashing', () => { const div = document.createElement('div'); ReactDOM.render(, div); diff --git a/cvat-ui/src/components/dashboard/header/dashboard-header.tsx b/cvat-ui/src/components/dashboard-page/header/dashboard-header.tsx similarity index 100% rename from cvat-ui/src/components/dashboard/header/dashboard-header.tsx rename to cvat-ui/src/components/dashboard-page/header/dashboard-header.tsx diff --git a/cvat-ui/src/components/login/login.scss b/cvat-ui/src/components/login-page/login-page.scss similarity index 100% rename from cvat-ui/src/components/login/login.scss rename to cvat-ui/src/components/login-page/login-page.scss diff --git a/cvat-ui/src/components/login/login.test.tsx b/cvat-ui/src/components/login-page/login-page.test.tsx similarity index 86% rename from cvat-ui/src/components/login/login.test.tsx rename to cvat-ui/src/components/login-page/login-page.test.tsx index 885191e2..6bec1fa7 100644 --- a/cvat-ui/src/components/login/login.test.tsx +++ b/cvat-ui/src/components/login-page/login-page.test.tsx @@ -1,6 +1,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import Login from './login'; + +import Login from './login-page'; + it('renders without crashing', () => { const div = document.createElement('div'); diff --git a/cvat-ui/src/components/login/login.tsx b/cvat-ui/src/components/login-page/login-page.tsx similarity index 90% rename from cvat-ui/src/components/login/login.tsx rename to cvat-ui/src/components/login-page/login-page.tsx index 7e28942f..8269844a 100644 --- a/cvat-ui/src/components/login/login.tsx +++ b/cvat-ui/src/components/login-page/login-page.tsx @@ -4,18 +4,24 @@ import { connect } from 'react-redux'; import { loginAsync } from '../../actions/auth.actions'; import { Button, Icon, Input, Form, Col, Row } from 'antd'; - -import './login.scss'; import Title from 'antd/lib/typography/Title'; +import './login-page.scss'; + class LoginForm extends PureComponent { + componentWillMount() { + if (localStorage.getItem('session')) { + this.props.history.push('/dashboard'); + } + } + render() { const { getFieldDecorator } = this.props.form; return ( - +
Login @@ -63,7 +69,7 @@ class LoginForm extends PureComponent { this.props.form.validateFields((error: any, values: any) => { if (!error) { - this.props.dispatch(loginAsync(values.username, values.password)) + this.props.dispatch(loginAsync(values.username, values.password, this.props.history)); } }); } diff --git a/cvat-ui/src/components/not-found/not-found.scss b/cvat-ui/src/components/page-not-found/page-not-found.scss similarity index 100% rename from cvat-ui/src/components/not-found/not-found.scss rename to cvat-ui/src/components/page-not-found/page-not-found.scss diff --git a/cvat-ui/src/components/not-found/not-found.test.tsx b/cvat-ui/src/components/page-not-found/page-not-found.test.tsx similarity index 84% rename from cvat-ui/src/components/not-found/not-found.test.tsx rename to cvat-ui/src/components/page-not-found/page-not-found.test.tsx index 8dbc7a01..101c2cc0 100644 --- a/cvat-ui/src/components/not-found/not-found.test.tsx +++ b/cvat-ui/src/components/page-not-found/page-not-found.test.tsx @@ -1,6 +1,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import NotFound from './not-found'; + +import NotFound from './page-not-found'; + it('renders without crashing', () => { const div = document.createElement('div'); diff --git a/cvat-ui/src/components/not-found/not-found.tsx b/cvat-ui/src/components/page-not-found/page-not-found.tsx similarity index 72% rename from cvat-ui/src/components/not-found/not-found.tsx rename to cvat-ui/src/components/page-not-found/page-not-found.tsx index 9e23b429..380782a7 100644 --- a/cvat-ui/src/components/not-found/not-found.tsx +++ b/cvat-ui/src/components/page-not-found/page-not-found.tsx @@ -2,9 +2,9 @@ import React, { PureComponent } from 'react'; import { Empty, Button } from 'antd'; -import './not-found.scss'; +import './page-not-found.scss'; -class NotFound extends PureComponent { +class PageNotFound extends PureComponent { render() { return( @@ -16,4 +16,4 @@ class NotFound extends PureComponent { } } -export default NotFound; +export default PageNotFound; diff --git a/cvat-ui/src/components/register-page/register-page.scss b/cvat-ui/src/components/register-page/register-page.scss new file mode 100644 index 00000000..0e46e1a8 --- /dev/null +++ b/cvat-ui/src/components/register-page/register-page.scss @@ -0,0 +1,10 @@ +.register-form { + display: flex; + flex-direction: column; + justify-content: center; + height: 100vh; + + &__title { + + } +} diff --git a/cvat-ui/src/components/register-page/register-page.test.tsx b/cvat-ui/src/components/register-page/register-page.test.tsx new file mode 100644 index 00000000..2b96c1a7 --- /dev/null +++ b/cvat-ui/src/components/register-page/register-page.test.tsx @@ -0,0 +1,11 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; + +import RegisterPage from './register-page'; + + +it('renders without crashing', () => { + const div = document.createElement('div'); + ReactDOM.render(, div); + ReactDOM.unmountComponentAtNode(div); +}); diff --git a/cvat-ui/src/components/register-page/register-page.tsx b/cvat-ui/src/components/register-page/register-page.tsx new file mode 100644 index 00000000..f93a7175 --- /dev/null +++ b/cvat-ui/src/components/register-page/register-page.tsx @@ -0,0 +1,188 @@ +import React, { PureComponent } from 'react'; + +import { connect } from 'react-redux'; +// import { registerAsync } from '../../actions/auth.actions'; + +import { Button, Icon, Input, Form, Col, Row } from 'antd'; +import Title from 'antd/lib/typography/Title'; + +import './register-page.scss'; + + +class RegisterForm extends PureComponent { + constructor(props: any) { + super(props); + + this.state = { confirmDirty: false }; + } + + componentWillMount() { + if (localStorage.getItem('session')) { + this.props.history.push('/dashboard'); + } + } + + render() { + const { getFieldDecorator } = this.props.form; + + return ( + + + + Register + + + {getFieldDecorator('username', { + rules: [{ required: true, message: 'Please enter your username!' }], + })( + } + type="text" + name="username" + placeholder="Username" + />, + )} + + + + {getFieldDecorator('firstName', { + rules: [], + })( + } + type="text" + name="first-name" + placeholder="First name" + />, + )} + + + + {getFieldDecorator('lastName', { + rules: [], + })( + } + type="text" + name="last-name" + placeholder="Last name" + />, + )} + + + + {getFieldDecorator('email', { + rules: [ + { + type: 'email', + message: 'The input is not valid email!', + }, + { + required: true, + message: 'Please input your email!', + }, + ], + })( + } + type="text" + name="email" + placeholder="Email" + />, + )} + + + + {getFieldDecorator('password', { + rules: [ + { + required: true, + message: 'Please input your password!', + }, + { + validator: this.validateToNextPassword, + }, + ], + })( + } + name="password" + placeholder="Password" + />, + )} + + + + {getFieldDecorator('passwordConfirmation', { + rules: [ + { + required: true, + message: 'Please confirm your password!', + }, + { + validator: this.compareToFirstPassword, + }, + ], + })( + } + name="password-confirmation" + placeholder="Password confirmation" + />, + )} + + + + + + + + + ); + } + + private handleConfirmBlur = (event: any) => { + const { value } = event.target; + + this.setState({ confirmDirty: this.state.confirmDirty || !!value }); + }; + + private compareToFirstPassword = (rule: any, value: string, callback: Function) => { + const { form } = this.props; + + if (value && value !== form.getFieldValue('password')) { + callback('Two passwords that you enter are inconsistent!'); + } else { + callback(); + } + }; + + private validateToNextPassword = (rule: any, value: string, callback: Function) => { + const { form } = this.props; + + if (value && this.state.confirmDirty) { + form.validateFields(['passwordConfirmation'], { force: true }); + } + + callback(); + }; + + private onSubmit = (event: any) => { + event.preventDefault(); + + this.props.form.validateFields((error: any, values: any) => { + if (!error) { + // this.props.dispatch(registerAsync(values.username, values.password, this.props.history)); + } + }); + } +} + +const mapStateToProps = (state: any) => { + return state.authContext; +}; + +export default Form.create()(connect(mapStateToProps)(RegisterForm)); diff --git a/cvat-ui/src/index.tsx b/cvat-ui/src/index.tsx index 5c66f5c5..d6d9cc2f 100644 --- a/cvat-ui/src/index.tsx +++ b/cvat-ui/src/index.tsx @@ -1,13 +1,15 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux' +import { Provider } from 'react-redux' import configureStore from './store'; +import App from './components/app/app'; + import * as serviceWorker from './serviceWorker'; import './index.scss'; -import App from './components/app/app'; + ReactDOM.render( diff --git a/cvat-ui/src/store.ts b/cvat-ui/src/store.ts index 244f5187..acb780b5 100644 --- a/cvat-ui/src/store.ts +++ b/cvat-ui/src/store.ts @@ -1,14 +1,27 @@ import { createStore, applyMiddleware, compose } from 'redux'; import thunk from 'redux-thunk'; +import { createLogger } from 'redux-logger' import rootReducer from './reducers/root.reducer'; export default function configureStore(initialState = {}) { + const logger = createLogger({ + collapsed: true, + }); + + const middlewares = []; + + if (process.env.NODE_ENV === `development`) { + middlewares.push(logger); + } + + middlewares.push(thunk); + return createStore( rootReducer, initialState, compose( - applyMiddleware(thunk), + applyMiddleware(...middlewares), (window as any).__REDUX_DEVTOOLS_EXTENSION__ ? (window as any).__REDUX_DEVTOOLS_EXTENSION__({ trace: true }) diff --git a/cvat-ui/src/utils/.gitkeep b/cvat-ui/src/utils/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/cvat-ui/src/utils/tasks-filter-dto.ts b/cvat-ui/src/utils/tasks-filter-dto.ts new file mode 100644 index 00000000..c57045dc --- /dev/null +++ b/cvat-ui/src/utils/tasks-filter-dto.ts @@ -0,0 +1,13 @@ +export default (params: { search?: string, page?: string }): { search?: string, page?: number } => { + const queryObject: { search?: string, page?: number } = {}; + + if (params['search']) { + queryObject.search = params.search.toString(); + } + + if (params['page']) { + queryObject.page = parseInt(params.page); + } + + return queryObject; +}