From 5c948e1a68d93dac97e922f54a706350240dfdcc Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 22 May 2021 18:10:12 +0200 Subject: [PATCH] Support for keyboard navigation for Apps. Small refactor to pinApp action --- .../src/components/Apps/AppForm/AppForm.tsx | 11 +++++++- .../src/components/Apps/AppTable/AppTable.tsx | 28 +++++++++++++++---- client/src/components/Apps/Apps.tsx | 11 ++++++-- client/src/store/actions/app.ts | 3 +- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/client/src/components/Apps/AppForm/AppForm.tsx b/client/src/components/Apps/AppForm/AppForm.tsx index f46c7e7..8a71b4e 100644 --- a/client/src/components/Apps/AppForm/AppForm.tsx +++ b/client/src/components/Apps/AppForm/AppForm.tsx @@ -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(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} />
diff --git a/client/src/components/Apps/AppTable/AppTable.tsx b/client/src/components/Apps/AppTable/AppTable.tsx index 072da58..ec0a11c 100644 --- a/client/src/components/Apps/AppTable/AppTable.tsx +++ b/client/src/components/Apps/AppTable/AppTable.tsx @@ -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 (
@@ -42,16 +49,27 @@ const AppTable = (props: ComponentProps): JSX.Element => { diff --git a/client/src/components/Apps/Apps.tsx b/client/src/components/Apps/Apps.tsx index e79696c..9b26111 100644 --- a/client/src/components/Apps/Apps.tsx +++ b/client/src/components/Apps/Apps.tsx @@ -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 && + + }
@@ -115,4 +120,4 @@ const mapStateToProps = (state: GlobalState) => { } } -export default connect(mapStateToProps, { getApps, pinApp, addApp })(Apps); \ No newline at end of file +export default connect(mapStateToProps, { getApps, addApp })(Apps); \ No newline at end of file diff --git a/client/src/store/actions/app.ts b/client/src/store/actions/app.ts index d66f325..0ba2c3f 100644 --- a/client/src/store/actions/app.ts +++ b/client/src/store/actions/app.ts @@ -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>(`/api/apps/${id}`, { isPinned: !isPinned }); dispatch({
deleteAppHandler(app)}> + onClick={() => deleteAppHandler(app)} + onKeyDown={(e) => keyboardActionHandler(e, app, deleteAppHandler)} + tabIndex={0}>
props.updateAppHandler(app)}> + onClick={() => props.updateAppHandler(app)} + onKeyDown={(e) => keyboardActionHandler(e, app, props.updateAppHandler)} + tabIndex={0}>
-
props.pinApp(app.id, app.isPinned)}> - {app.isPinned? : } +
props.pinApp(app)} + onKeyDown={(e) => keyboardActionHandler(e, app, props.pinApp)} + tabIndex={0}> + {app.isPinned + ? + : + }