mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-04-24 20:36:40 +07:00
ScrollDialog error handling
This commit is contained in:
parent
bfc779745a
commit
a977c73449
5 changed files with 42 additions and 11 deletions
|
@ -1,4 +1,4 @@
|
||||||
import React, {FC, FormEvent, useCallback, useEffect, useState} from 'react';
|
import React, { FC, FormEvent, useCallback, useEffect, useState } from 'react';
|
||||||
import { ScrollDialog } from '../ScrollDialog';
|
import { ScrollDialog } from '../ScrollDialog';
|
||||||
import { IDialogProps } from '~/redux/modal/constants';
|
import { IDialogProps } from '~/redux/modal/constants';
|
||||||
import { useCloseOnEscape } from '~/utils/hooks';
|
import { useCloseOnEscape } from '~/utils/hooks';
|
||||||
|
@ -7,9 +7,9 @@ import { InputText } from '~/components/input/InputText';
|
||||||
import { Button } from '~/components/input/Button';
|
import { Button } from '~/components/input/Button';
|
||||||
import { Padder } from '~/components/containers/Padder';
|
import { Padder } from '~/components/containers/Padder';
|
||||||
import * as styles from './styles.scss';
|
import * as styles from './styles.scss';
|
||||||
import {selectAuthLogin} from "~/redux/auth/selectors";
|
import { selectAuthLogin } from "~/redux/auth/selectors";
|
||||||
import * as ACTIONS from '~/redux/auth/actions';
|
import * as ACTIONS from '~/redux/auth/actions';
|
||||||
import {connect} from "react-redux";
|
import { connect } from "react-redux";
|
||||||
|
|
||||||
const mapStateToProps = selectAuthLogin;
|
const mapStateToProps = selectAuthLogin;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ const mapDispatchToProps = {
|
||||||
|
|
||||||
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & IDialogProps & {};
|
type IProps = ReturnType<typeof mapStateToProps> & typeof mapDispatchToProps & IDialogProps & {};
|
||||||
|
|
||||||
const LoginDialogUnconnected: FC<IProps> = ({ onRequestClose, error , userSendLoginRequest, userSetLoginError }) => {
|
const LoginDialogUnconnected: FC<IProps> = ({ onRequestClose, error, userSendLoginRequest, userSetLoginError }) => {
|
||||||
const [username, setUserName] = useState('');
|
const [username, setUserName] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ const LoginDialogUnconnected: FC<IProps> = ({ onRequestClose, error , userSendLo
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
<ScrollDialog buttons={buttons} width={260}>
|
<ScrollDialog buttons={buttons} width={260} error={error}>
|
||||||
<Padder>
|
<Padder>
|
||||||
<div className={styles.wrap}>
|
<div className={styles.wrap}>
|
||||||
<Group>
|
<Group>
|
||||||
|
@ -56,7 +56,7 @@ const LoginDialogUnconnected: FC<IProps> = ({ onRequestClose, error , userSendLo
|
||||||
<div />
|
<div />
|
||||||
<div />
|
<div />
|
||||||
|
|
||||||
<InputText title="Логин" handler={setUserName} value={username} error={error} />
|
<InputText title="Логин" handler={setUserName} value={username} />
|
||||||
<InputText title="Пароль" handler={setPassword} value={password} />
|
<InputText title="Пароль" handler={setPassword} value={password} />
|
||||||
</Group>
|
</Group>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -12,6 +12,7 @@ interface IProps {
|
||||||
width?: number;
|
width?: number;
|
||||||
onOverlayClick?: MouseEventHandler<HTMLDivElement>;
|
onOverlayClick?: MouseEventHandler<HTMLDivElement>;
|
||||||
onRefCapture?: (ref: any) => void;
|
onRefCapture?: (ref: any) => void;
|
||||||
|
error?: string;
|
||||||
|
|
||||||
top_sticky?: ReactChild;
|
top_sticky?: ReactChild;
|
||||||
top_sticky_offset?: number;
|
top_sticky_offset?: number;
|
||||||
|
@ -24,7 +25,7 @@ const ScrollDialog: FC<IProps> = ({
|
||||||
width = 800,
|
width = 800,
|
||||||
top_sticky,
|
top_sticky,
|
||||||
top_sticky_offset,
|
top_sticky_offset,
|
||||||
|
error,
|
||||||
onOverlayClick,
|
onOverlayClick,
|
||||||
onRefCapture
|
onRefCapture
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -94,6 +95,8 @@ const ScrollDialog: FC<IProps> = ({
|
||||||
{!!buttons && (
|
{!!buttons && (
|
||||||
<div className={styles.bottom}>
|
<div className={styles.bottom}>
|
||||||
<div className={styles.wrap} style={{ flexBasis: width }}>
|
<div className={styles.wrap} style={{ flexBasis: width }}>
|
||||||
|
<div className={classNames(styles.error, { active: error })}>{error}</div>
|
||||||
|
|
||||||
<div className={styles.pan}>{buttons}</div>
|
<div className={styles.pan}>{buttons}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -102,7 +105,7 @@ const ScrollDialog: FC<IProps> = ({
|
||||||
<div
|
<div
|
||||||
className={styles.scroll_wrap}
|
className={styles.scroll_wrap}
|
||||||
style={{ flexBasis: width + 40 }}
|
style={{ flexBasis: width + 40 }}
|
||||||
// style={{ flexBasis: width }}
|
// style={{ flexBasis: width }}
|
||||||
>
|
>
|
||||||
<Scroll
|
<Scroll
|
||||||
className="dialog_scroll"
|
className="dialog_scroll"
|
||||||
|
|
|
@ -54,7 +54,10 @@
|
||||||
height: 10px;
|
height: 10px;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
||||||
&:global(.has_buttons) { height: 60px; top: 15px;}
|
&:global(.has_buttons) {
|
||||||
|
height: 60px;
|
||||||
|
top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
.wrap {
|
.wrap {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -75,6 +78,7 @@
|
||||||
.wrap {
|
.wrap {
|
||||||
flex: 0 1 800px;
|
flex: 0 1 800px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scroll_wrap {
|
.scroll_wrap {
|
||||||
|
@ -126,3 +130,27 @@
|
||||||
bottom: -$gap;
|
bottom: -$gap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
background: linear-gradient(transparentize($red, 1), $red);
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 0;
|
||||||
|
padding: $gap * 2 $gap;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font: $font_14_regular;
|
||||||
|
border-radius: 0 0 $radius $radius;
|
||||||
|
pointer-events: none;
|
||||||
|
touch-action: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.25s;
|
||||||
|
|
||||||
|
&:global(.active) {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ export interface IModalState {
|
||||||
|
|
||||||
const INITIAL_STATE: IModalState = {
|
const INITIAL_STATE: IModalState = {
|
||||||
is_shown: true,
|
is_shown: true,
|
||||||
dialog: DIALOGS.EDITOR,
|
dialog: DIALOGS.LOGIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default createReducer(INITIAL_STATE, MODAL_HANDLERS);
|
export default createReducer(INITIAL_STATE, MODAL_HANDLERS);
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { IState } from "~/redux/store";
|
||||||
|
|
||||||
const authPersistConfig: PersistConfig = {
|
const authPersistConfig: PersistConfig = {
|
||||||
key: "auth",
|
key: "auth",
|
||||||
whitelist: ["token"],
|
whitelist: ["token", "user"],
|
||||||
storage
|
storage
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue