From 882f011d07a6df56fa498a539cc2d52be176612e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Malak?= Date: Sat, 20 Nov 2021 14:51:47 +0100 Subject: [PATCH] Cleaned up Apps and Bookmarks containers. Changed AppTable to use TableActions component --- .../src/components/Apps/AppTable/AppTable.tsx | 142 ++++++------------ client/src/components/Apps/Apps.tsx | 27 ++-- client/src/components/Bookmarks/Bookmarks.tsx | 91 ++++++----- 3 files changed, 114 insertions(+), 146 deletions(-) diff --git a/client/src/components/Apps/AppTable/AppTable.tsx b/client/src/components/Apps/AppTable/AppTable.tsx index ee82144..aa23797 100644 --- a/client/src/components/Apps/AppTable/AppTable.tsx +++ b/client/src/components/Apps/AppTable/AppTable.tsx @@ -1,4 +1,4 @@ -import { Fragment, KeyboardEvent, useState, useEffect } from 'react'; +import { Fragment, useState, useEffect } from 'react'; import { DragDropContext, Droppable, @@ -9,21 +9,20 @@ import { Link } from 'react-router-dom'; // Redux import { useDispatch, useSelector } from 'react-redux'; - -// Typescript -import { App } from '../../../interfaces'; - -// CSS -import classes from './AppTable.module.css'; - -// UI -import { Icon, Table } from '../../UI'; import { State } from '../../../store/reducers'; import { bindActionCreators } from 'redux'; import { actionCreators } from '../../../store'; +// Typescript +import { App } from '../../../interfaces'; + +// Other +import classes from './AppTable.module.css'; +import { Table } from '../../UI'; +import { TableActions } from '../../Actions/TableActions'; + interface Props { - updateAppHandler: (app: App) => void; + openFormForUpdating: (app: App) => void; } export const AppTable = (props: Props): JSX.Element => { @@ -33,49 +32,18 @@ export const AppTable = (props: Props): JSX.Element => { } = useSelector((state: State) => state); const dispatch = useDispatch(); - const { pinApp, deleteApp, reorderApps, updateConfig, createNotification } = + const { pinApp, deleteApp, reorderApps, createNotification, updateApp } = bindActionCreators(actionCreators, dispatch); const [localApps, setLocalApps] = useState([]); - const [isCustomOrder, setIsCustomOrder] = useState(false); // Copy apps array useEffect(() => { setLocalApps([...apps]); }, [apps]); - // Check ordering - useEffect(() => { - const order = config.useOrdering; - - if (order === 'orderId') { - setIsCustomOrder(true); - } - }, []); - - const deleteAppHandler = (app: App): void => { - const proceed = window.confirm( - `Are you sure you want to delete ${app.name} at ${app.url} ?` - ); - - if (proceed) { - deleteApp(app.id); - } - }; - - // Support keyboard navigation for actions - const keyboardActionHandler = ( - e: KeyboardEvent, - app: App, - handler: Function - ) => { - if (e.key === 'Enter') { - handler(app); - } - }; - const dragEndHanlder = (result: DropResult): void => { - if (!isCustomOrder) { + if (config.useOrdering !== 'orderId') { createNotification({ title: 'Error', message: 'Custom order is disabled', @@ -95,18 +63,43 @@ export const AppTable = (props: Props): JSX.Element => { reorderApps(tmpApps); }; + // Action handlers + const deleteAppHandler = (id: number, name: string) => { + const proceed = window.confirm(`Are you sure you want to delete ${name}?`); + + if (proceed) { + deleteApp(id); + } + }; + + const updateAppHandler = (id: number) => { + const app = apps.find((a) => a.id === id) as App; + props.openFormForUpdating(app); + }; + + const pinAppHandler = (id: number) => { + const app = apps.find((a) => a.id === id) as App; + pinApp(app); + }; + + const changeAppVisibiltyHandler = (id: number) => { + const app = apps.find((a) => a.id === id) as App; + updateApp(id, { ...app, isPublic: !app.isPublic }); + }; + return (
- {isCustomOrder ? ( + {config.useOrdering === 'orderId' ? (

You can drag and drop single rows to reorder application

) : (

- Custom order is disabled. You can change it in{' '} - settings + Custom order is disabled. You can change it in the{' '} + settings

)}
+ {(provided) => ( @@ -143,54 +136,15 @@ export const AppTable = (props: Props): JSX.Element => { {app.isPublic ? 'Visible' : 'Hidden'} + {!snapshot.isDragging && ( - -
deleteAppHandler(app)} - onKeyDown={(e) => - keyboardActionHandler( - e, - app, - deleteAppHandler - ) - } - tabIndex={0} - > - -
-
props.updateAppHandler(app)} - onKeyDown={(e) => - keyboardActionHandler( - e, - app, - props.updateAppHandler - ) - } - tabIndex={0} - > - -
-
pinApp(app)} - onKeyDown={(e) => - keyboardActionHandler(e, app, pinApp) - } - tabIndex={0} - > - {app.isPinned ? ( - - ) : ( - - )} -
- + )} ); diff --git a/client/src/components/Apps/Apps.tsx b/client/src/components/Apps/Apps.tsx index 9ccb0d4..7231e18 100644 --- a/client/src/components/Apps/Apps.tsx +++ b/client/src/components/Apps/Apps.tsx @@ -29,44 +29,49 @@ interface Props { } export const Apps = (props: Props): JSX.Element => { + // Get Redux state const { apps: { apps, loading }, auth: { isAuthenticated }, } = useSelector((state: State) => state); + // Get Redux action creators const dispatch = useDispatch(); const { getApps } = bindActionCreators(actionCreators, dispatch); - const [modalIsOpen, setModalIsOpen] = useState(false); - const [isInEdit, setIsInEdit] = useState(false); - const [isInUpdate, setIsInUpdate] = useState(false); - const [appInUpdate, setAppInUpdate] = useState(appTemplate); - + // Load apps if array is empty useEffect(() => { if (!apps.length) { getApps(); } }, []); - // observe if user is authenticated -> set default view if not + // Form + const [modalIsOpen, setModalIsOpen] = useState(false); + const [showTable, setShowTable] = useState(false); + const [isInUpdate, setIsInUpdate] = useState(false); + const [appInUpdate, setAppInUpdate] = useState(appTemplate); + + // Observe if user is authenticated -> set default view if not useEffect(() => { if (!isAuthenticated) { - setIsInEdit(false); + setShowTable(false); setModalIsOpen(false); } }, [isAuthenticated]); + // Form actions const toggleModal = (): void => { setModalIsOpen(!modalIsOpen); setIsInUpdate(false); }; const toggleEdit = (): void => { - setIsInEdit(!isInEdit); + setShowTable(!showTable); setIsInUpdate(false); }; - const toggleUpdate = (app: App): void => { + const openFormForUpdating = (app: App): void => { setAppInUpdate(app); setIsInUpdate(true); setModalIsOpen(true); @@ -97,10 +102,10 @@ export const Apps = (props: Props): JSX.Element => {
{loading ? ( - ) : !isInEdit ? ( + ) : !showTable ? ( ) : ( - + )}
diff --git a/client/src/components/Bookmarks/Bookmarks.tsx b/client/src/components/Bookmarks/Bookmarks.tsx index 62a2e15..ba5570e 100644 --- a/client/src/components/Bookmarks/Bookmarks.tsx +++ b/client/src/components/Bookmarks/Bookmarks.tsx @@ -18,11 +18,11 @@ import { Container, Headline, ActionButton, Spinner, Modal } from '../UI'; // Components import { BookmarkGrid } from './BookmarkGrid/BookmarkGrid'; -import { BookmarkTable } from './BookmarkTable/BookmarkTable'; import { Form } from './Form/Form'; // Utils import { bookmarkTemplate, categoryTemplate } from '../../utility'; +import { Table } from './Table/Table'; interface Props { searching: boolean; @@ -34,66 +34,64 @@ export enum ContentType { } export const Bookmarks = (props: Props): JSX.Element => { + // Get Redux state const { bookmarks: { loading, categories }, auth: { isAuthenticated }, } = useSelector((state: State) => state); + // Get Redux action creators const dispatch = useDispatch(); const { getCategories } = bindActionCreators(actionCreators, dispatch); - const [modalIsOpen, setModalIsOpen] = useState(false); - const [formContentType, setFormContentType] = useState(ContentType.category); - const [isInEdit, setIsInEdit] = useState(false); - const [tableContentType, setTableContentType] = useState( - ContentType.category - ); - const [isInUpdate, setIsInUpdate] = useState(false); - const [categoryInUpdate, setCategoryInUpdate] = - useState(categoryTemplate); - const [bookmarkInUpdate, setBookmarkInUpdate] = - useState(bookmarkTemplate); - + // Load categories if array is empty useEffect(() => { if (!categories.length) { getCategories(); } }, []); - // observe if user is authenticated -> set default view if not + // Form + const [modalIsOpen, setModalIsOpen] = useState(false); + const [formContentType, setFormContentType] = useState(ContentType.category); + const [isInUpdate, setIsInUpdate] = useState(false); + const [categoryInUpdate, setCategoryInUpdate] = + useState(categoryTemplate); + const [bookmarkInUpdate, setBookmarkInUpdate] = + useState(bookmarkTemplate); + + // Table + const [showTable, setShowTable] = useState(false); + const [tableContentType, setTableContentType] = useState( + ContentType.category + ); + + // Observe if user is authenticated -> set default view (grid) if not useEffect(() => { if (!isAuthenticated) { - setIsInEdit(false); + setShowTable(false); setModalIsOpen(false); } }, [isAuthenticated]); + // Form actions const toggleModal = (): void => { setModalIsOpen(!modalIsOpen); }; - const addActionHandler = (contentType: ContentType) => { + const openFormForAdding = (contentType: ContentType) => { setFormContentType(contentType); setIsInUpdate(false); toggleModal(); }; - const editActionHandler = (contentType: ContentType) => { - // We're in the edit mode and the same button was clicked - go back to list - if (isInEdit && contentType === tableContentType) { - setIsInEdit(false); - } else { - setIsInEdit(true); - setTableContentType(contentType); - } - }; - - const instanceOfCategory = (object: any): object is Category => { - return 'bookmarks' in object; - }; - - const goToUpdateMode = (data: Category | Bookmark): void => { + const openFormForUpdating = (data: Category | Bookmark): void => { setIsInUpdate(true); + + const instanceOfCategory = (object: any): object is Category => { + return 'bookmarks' in object; + }; + if (instanceOfCategory(data)) { setFormContentType(ContentType.category); setCategoryInUpdate(data); @@ -101,9 +99,21 @@ export const Bookmarks = (props: Props): JSX.Element => { setFormContentType(ContentType.bookmark); setBookmarkInUpdate(data); } + toggleModal(); }; + // Table actions + const showTableForEditing = (contentType: ContentType) => { + // We're in the edit mode and the same button was clicked - go back to list + if (showTable && contentType === tableContentType) { + setShowTable(false); + } else { + setShowTable(true); + setTableContentType(contentType); + } + }; + return ( @@ -123,35 +133,34 @@ export const Bookmarks = (props: Props): JSX.Element => { addActionHandler(ContentType.category)} + handler={() => openFormForAdding(ContentType.category)} /> addActionHandler(ContentType.bookmark)} + handler={() => openFormForAdding(ContentType.bookmark)} /> editActionHandler(ContentType.category)} + handler={() => showTableForEditing(ContentType.category)} /> - editActionHandler(ContentType.bookmark)} - /> + handler={() => showTableForEditing(ContentType.bookmark)} + /> */} )} {loading ? ( - ) : !isInEdit ? ( + ) : !showTable ? ( ) : ( - )}