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

Improved UX of signing pages #5295

Merged
merged 6 commits into from
Nov 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Mask tools are supported now (brush, eraser, polygon-plus, polygon-minus, returning masks
from online detectors & interactors) (<https://github.com/opencv/cvat/pull/4543>)
- Added Webhooks (<https://github.com/opencv/cvat/pull/4863>)
- Authentication with social accounts google & github (<https://github.com/opencv/cvat/pull/5147>, <https://github.com/opencv/cvat/pull/5181>)
- Authentication with social accounts google & github (<https://github.com/opencv/cvat/pull/5147>, <https://github.com/opencv/cvat/pull/5181>, <https://github.com/opencv/cvat/pull/5295>)
- REST API tests to export job datasets & annotations and validate their structure (<https://github.com/opencv/cvat/pull/5160>)

### Changed
Expand Down
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.44.0",
"version": "1.44.1",
"description": "CVAT single-page application",
"main": "src/index.tsx",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion cvat-ui/src/assets/cvat-minimalistic-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 6 additions & 6 deletions cvat-ui/src/components/header/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@
}
}

.anticon.cvat-logo-icon {
> svg {
transform: scale(0.7);
}
}

width: 50%;
display: flex;
justify-content: flex-start;
Expand All @@ -49,12 +55,6 @@
}
}

.anticon.cvat-logo-icon {
> svg {
transform: scale(0.7);
}
}

.cvat-header-menu-user-dropdown {
display: flex;
align-items: center;
Expand Down
39 changes: 17 additions & 22 deletions cvat-ui/src/components/login-page/login-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: MIT

import React, { useCallback, useState } from 'react';
import React, { useState } from 'react';
import Form from 'antd/lib/form';
import Button from 'antd/lib/button';
import Input from 'antd/lib/input';
Expand All @@ -15,6 +15,7 @@ import { Col, Row } from 'antd/lib/grid';
import Title from 'antd/lib/typography/Title';
import Text from 'antd/lib/typography/Text';
import { Link } from 'react-router-dom';
import CVATSigningInput, { CVATInputType } from 'components/signing-common/cvat-signing-input';

export interface LoginData {
credential: string;
Expand All @@ -35,9 +36,6 @@ function LoginFormComponent(props: Props): JSX.Element {
const [form] = Form.useForm();
const [credential, setCredential] = useState('');

const inputReset = useCallback((name: string):void => {
form.setFieldsValue({ [name]: '' });
}, [form]);
const forgotPasswordLink = (
<Col className='cvat-credentials-link'>
<Text strong>
Expand Down Expand Up @@ -97,23 +95,21 @@ function LoginFormComponent(props: Props): JSX.Element {
>
<Input
autoComplete='credential'
placeholder='enter your email or username'
prefix={<Text>Email or username</Text>}
suffix={(
credential && (
<Icon
component={ClearIcon}
onClick={() => {
setCredential('');
inputReset('credential');
}}
/>
)
className={credential ? 'cvat-input-floating-label-above' : 'cvat-input-floating-label'}
suffix={credential && (
<Icon
component={ClearIcon}
onClick={() => {
setCredential('');
form.setFieldsValue({ credential: '', password: '' });
}}
/>
)}
onChange={(event) => {
const { value } = event.target;
setCredential(value);
if (!value) inputReset('credential');
if (!value) form.setFieldsValue({ credential: '', password: '' });
}}
/>
</Form.Item>
Expand All @@ -129,12 +125,11 @@ function LoginFormComponent(props: Props): JSX.Element {
},
]}
>
<Input.Password
autoComplete='current-password'
placeholder='enter your password'
prefix={
<Text>Password</Text>
}
<CVATSigningInput
type={CVATInputType.PASSWORD}
id='password'
placeholder='Password'
autoComplete='password'
/>
</Form.Item>
)
Expand Down
41 changes: 18 additions & 23 deletions cvat-ui/src/components/register-page/register-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,10 @@
//
// SPDX-License-Identifier: MIT

import React, { useCallback, useState } from 'react';
import React, { useState } from 'react';
import Icon from '@ant-design/icons';
import Form, { RuleRender, RuleObject } from 'antd/lib/form';
import Button from 'antd/lib/button';
import Input from 'antd/lib/input';
import Text from 'antd/lib/typography/Text';
import Checkbox from 'antd/lib/checkbox';
import { Link } from 'react-router-dom';
import { BackArrowIcon } from 'icons';
Expand All @@ -17,7 +15,7 @@ import patterns from 'utils/validation-patterns';

import { UserAgreement } from 'reducers';
import { Row, Col } from 'antd/lib/grid';
import CVATSigningInput from 'components/signing-common/cvat-signing-input';
import CVATSigningInput, { CVATInputType } from 'components/signing-common/cvat-signing-input';

export interface UserConfirmation {
name: string;
Expand Down Expand Up @@ -104,9 +102,6 @@ function RegisterFormComponent(props: Props): JSX.Element {
const { fetching, onSubmit, userAgreements } = props;
const [form] = Form.useForm();
const [usernameEdited, setUsernameEdited] = useState(false);
const inputReset = useCallback((name: string):void => {
form.setFieldsValue({ [name]: '' });
}, [form]);
return (
<div className={`cvat-register-form-wrapper ${userAgreements.length ? 'cvat-register-form-wrapper-extended' : ''}`}>
<Row justify='space-between' className='cvat-credentials-navigation'>
Expand Down Expand Up @@ -146,9 +141,9 @@ function RegisterFormComponent(props: Props): JSX.Element {
>
<CVATSigningInput
id='firstName'
placeholder='enter your first name'
prefix='First name'
onReset={() => inputReset('firstName')}
placeholder='First name'
autoComplete='given-name'
onReset={() => form.setFieldsValue({ firstName: '' })}
/>
</Form.Item>
</Col>
Expand All @@ -166,9 +161,9 @@ function RegisterFormComponent(props: Props): JSX.Element {
>
<CVATSigningInput
id='lastName'
placeholder='enter your last name'
prefix='Last name'
onReset={() => inputReset('lastName')}
placeholder='Last name'
autoComplete='family-name'
onReset={() => form.setFieldsValue({ lastName: '' })}
/>
</Form.Item>
</Col>
Expand All @@ -190,9 +185,8 @@ function RegisterFormComponent(props: Props): JSX.Element {
<CVATSigningInput
id='email'
autoComplete='email'
placeholder='enter your email'
prefix='Email'
onReset={() => inputReset('email')}
placeholder='Email'
onReset={() => form.setFieldsValue({ email: '', username: '' })}
onChange={(event) => {
const { value } = event.target;
if (!usernameEdited) {
Expand All @@ -217,9 +211,9 @@ function RegisterFormComponent(props: Props): JSX.Element {
>
<CVATSigningInput
id='username'
placeholder='enter your username'
prefix='Username'
onReset={() => inputReset('username')}
placeholder='Username'
autoComplete='username'
onReset={() => form.setFieldsValue({ username: '' })}
onChange={() => setUsernameEdited(true)}
/>
</Form.Item>
Expand All @@ -233,12 +227,13 @@ function RegisterFormComponent(props: Props): JSX.Element {
}, validatePassword,
]}
>
<Input.Password
placeholder='enter your password'
prefix={<Text>Password</Text>}
<CVATSigningInput
type={CVATInputType.PASSWORD}
id='password1'
placeholder='Password'
autoComplete='new-password'
/>
</Form.Item>

{userAgreements.map((userAgreement: UserAgreement): JSX.Element => (
<Form.Item
className='cvat-agreements-form-item'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//
// SPDX-License-Identifier: MIT

import React, { useCallback } from 'react';
import React from 'react';
import Form from 'antd/lib/form';
import Button from 'antd/lib/button';
import Icon from '@ant-design/icons';
Expand All @@ -28,9 +28,6 @@ function ResetPasswordFormComponent({ fetching, onSubmit }: Props): JSX.Element
const location = useLocation();
const params = new URLSearchParams(location.search);
const defaultCredential = params.get('credential');
const inputReset = useCallback((name: string):void => {
form.setFieldsValue({ [name]: '' });
}, [form]);
return (
<div className='cvat-password-reset-form-wrapper'>
<Row justify='space-between' className='cvat-credentials-navigation'>
Expand Down Expand Up @@ -74,9 +71,8 @@ function ResetPasswordFormComponent({ fetching, onSubmit }: Props): JSX.Element
>
<CVATSigningInput
autoComplete='email'
placeholder='enter your email'
prefix='Email'
onReset={() => inputReset('email')}
placeholder='Email'
onReset={() => form.setFieldsValue({ email: '' })}
/>
</Form.Item>
<Row>
Expand Down
59 changes: 37 additions & 22 deletions cvat-ui/src/components/signing-common/cvat-signing-input.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,65 @@
// Copyright (C) 2022 CVAT.ai Corporation
//
// SPDX-License-Identifier: MIT
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import Icon from '@ant-design/icons';
import Text from 'antd/lib/typography/Text';
import { ClearIcon } from 'icons';
import { Input } from 'antd';
import Text from 'antd/lib/typography/Text';

interface SocialAccountLinkProps {
id?: string;
prefix: string;
autoComplete?: string;
placeholder: string;
value?: string;
onReset: () => void;
type?: CVATInputType;
onReset?: () => void;
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

export enum CVATInputType {
TEXT = 'text',
PASSWORD = 'passord',
}

function CVATSigningInput(props: SocialAccountLinkProps): JSX.Element {
const {
id, prefix, autoComplete, onReset, placeholder, value, onChange,
id, autoComplete, type, onReset, placeholder, value, onChange,
} = props;
const [valueNonEmpty, setValueNonEmpty] = useState(false);
useEffect((): void => {
setValueNonEmpty(!!value);
}, [value]);

if (type === CVATInputType.PASSWORD) {
return (
<Input.Password
value={value}
autoComplete={autoComplete}
className={valueNonEmpty ? 'cvat-input-floating-label-above' : 'cvat-input-floating-label'}
prefix={<Text>{placeholder}</Text>}
id={id}
onChange={onChange}
/>
);
}
return (
<Input
value={value}
autoComplete={autoComplete}
placeholder={placeholder}
prefix={<Text>{prefix}</Text>}
className={valueNonEmpty ? 'cvat-input-floating-label-above' : 'cvat-input-floating-label'}
prefix={<Text>{placeholder}</Text>}
id={id}
suffix={(
valueNonEmpty ? (
<Icon
component={ClearIcon}
onClick={() => {
setValueNonEmpty(false);
onReset();
}}
/>
) : null
suffix={valueNonEmpty && (
<Icon
component={ClearIcon}
onClick={() => {
setValueNonEmpty(false);
if (onReset) onReset();
}}
/>
)}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
const { value: inputValue } = event.target;
setValueNonEmpty(!!inputValue);
if (onChange) onChange(event);
}}
onChange={onChange}
/>
);
}
Expand Down
14 changes: 13 additions & 1 deletion cvat-ui/src/components/signing-common/signing-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,23 @@ function SignInLayout(props: SignInLayoutComponentProps): JSX.Element {
xl: { span: 8 },
xxl: { span: 10 },
};
const logoSizes = {
xs: { span: 21 },
sm: { span: 21 },
md: { span: 21 },
lg: { span: 21 },
xl: { span: 21 },
xxl: { span: 22 },
};
return (
<Layout>
<SVGSigningBackground className='cvat-signing-background' />
<Header className='cvat-signing-header'>
<Icon className='cvat-logo-icon' component={CVATMinimalisticLogo} />
<Row justify='center' align='middle'>
<Col {...logoSizes}>
<Icon className='cvat-logo-icon' component={CVATMinimalisticLogo} />
</Col>
</Row>
</Header>
<Layout className='cvat-signing-layout'>
<Content>
Expand Down
Loading