1
0
Fork 0
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:
muerwre 2019-08-06 19:09:07 +07:00
parent bfc779745a
commit a977c73449
5 changed files with 42 additions and 11 deletions

View file

@ -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>

View file

@ -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"

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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
}; };