Support for keyboard navigation for Apps. Small refactor to pinApp action

This commit is contained in:
unknown 2021-05-22 18:10:12 +02:00
parent 8813bf6181
commit 5c948e1a68
4 changed files with 43 additions and 10 deletions

View File

@ -1,4 +1,4 @@
import { useState, useEffect, ChangeEvent, SyntheticEvent } from 'react';
import { useState, useEffect, useRef, ChangeEvent, SyntheticEvent } from 'react';
import { connect } from 'react-redux';
import { addApp, updateApp } from '../../../store/actions';
import { App, NewApp } from '../../../interfaces/App';
@ -20,6 +20,14 @@ const AppForm = (props: ComponentProps): JSX.Element => {
icon: ''
});
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
if (inputRef.current) {
inputRef.current.focus();
}
}, [inputRef])
useEffect(() => {
if (props.app) {
console.log('app');
@ -75,6 +83,7 @@ const AppForm = (props: ComponentProps): JSX.Element => {
required
value={formData.name}
onChange={(e) => inputChangeHandler(e)}
ref={inputRef}
/>
</div>
<div className={classes.InputGroup}>

View File

@ -1,3 +1,4 @@
import { KeyboardEvent } from 'react';
import { connect } from 'react-redux';
import { App, GlobalState } from '../../../interfaces';
import { pinApp, deleteApp } from '../../../store/actions';
@ -7,7 +8,7 @@ import Icon from '../../UI/Icons/Icon/Icon';
interface ComponentProps {
apps: App[];
pinApp: (id: number, isPinned: boolean) => void;
pinApp: (app: App) => void;
deleteApp: (id: number) => void;
updateAppHandler: (app: App) => void;
}
@ -21,6 +22,12 @@ const AppTable = (props: ComponentProps): JSX.Element => {
}
}
const keyboardActionHandler = (e: KeyboardEvent, app: App, handler: Function) => {
if (e.key === 'Enter') {
handler(app);
}
}
return (
<div className={classes.TableContainer}>
<table className={classes.Table}>
@ -42,16 +49,27 @@ const AppTable = (props: ComponentProps): JSX.Element => {
<td className={classes.TableActions}>
<div
className={classes.TableAction}
onClick={() => deleteAppHandler(app)}>
onClick={() => deleteAppHandler(app)}
onKeyDown={(e) => keyboardActionHandler(e, app, deleteAppHandler)}
tabIndex={0}>
<Icon icon='mdiDelete' />
</div>
<div
className={classes.TableAction}
onClick={() => props.updateAppHandler(app)}>
onClick={() => props.updateAppHandler(app)}
onKeyDown={(e) => keyboardActionHandler(e, app, props.updateAppHandler)}
tabIndex={0}>
<Icon icon='mdiPencil' />
</div>
<div className={classes.TableAction} onClick={() => props.pinApp(app.id, app.isPinned)}>
{app.isPinned? <Icon icon='mdiPinOff' color='var(--color-accent)' /> : <Icon icon='mdiPin' />}
<div
className={classes.TableAction}
onClick={() => props.pinApp(app)}
onKeyDown={(e) => keyboardActionHandler(e, app, props.pinApp)}
tabIndex={0}>
{app.isPinned
? <Icon icon='mdiPinOff' color='var(--color-accent)' />
: <Icon icon='mdiPin' />
}
</div>
</td>
</tr>

View File

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { Fragment, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
// Redux
@ -25,7 +25,6 @@ import AppTable from './AppTable/AppTable';
interface ComponentProps {
getApps: Function;
pinApp: (id: number, isPinned: boolean) => void;
addApp: (formData: NewApp) => void;
apps: App[];
loading: boolean;
@ -92,6 +91,12 @@ const Apps = (props: ComponentProps): JSX.Element => {
icon='mdiPencil'
handler={toggleEdit}
/>
{isInEdit && <Fragment>
<ActionButton
name='Pin All'
icon='mdiPin'
/>
</Fragment>}
</div>
<div className={classes.Apps}>
@ -115,4 +120,4 @@ const mapStateToProps = (state: GlobalState) => {
}
}
export default connect(mapStateToProps, { getApps, pinApp, addApp })(Apps);
export default connect(mapStateToProps, { getApps, addApp })(Apps);

View File

@ -34,8 +34,9 @@ export interface PinAppAction {
payload: App;
}
export const pinApp = (id: number, isPinned: boolean) => async (dispatch: Dispatch) => {
export const pinApp = (app: App) => async (dispatch: Dispatch) => {
try {
const { id, isPinned} = app;
const res = await axios.put<ApiResponse<App>>(`/api/apps/${id}`, { isPinned: !isPinned });
dispatch<PinAppAction>({