From 8a76782660d7d46661ce960664d43a05b8d227fc Mon Sep 17 00:00:00 2001 From: Ian Skelskey Date: Mon, 20 May 2024 23:57:43 -0400 Subject: [PATCH] refactor: optimize TableEntry component and CSS adjustments This commit brings several optimizations and code structure improvements to the `TableEntry.jsx` component, alongside minor CSS adjustments to ensure consistent text color across light and dark themes. ### Optimizations and Adjustments: - Ensured consistent use of semicolons and removed unused imports. - Introduced `BINARY_KEYS`, `TRUE_KEYS`, and `FALSE_KEYS` constants for clearer handling of binary values within `TableEntry`. - Simplified and consolidated event handler functions (`handleEditClick`, `handleDeleteClick`, `handleSaveClick`, `handleCancelClick`) for cleaner, more readable code. - Utilized `useEffect` to set keys based on the current table name, refining the component's reactivity to prop changes. - Streamlined conditional rendering within the Actions component to improve readability. - Adjusted `select` CSS in `index.css` to ensure text color is explicitly set to black in light mode, addressing an inconsistency in theme styling. ### Code Cleanup: - Removed unnecessary checks and verbose conditions, adopting more straightforward logic for state management and event handling. - Simplified the mapping and rendering of `keys` by directly integrating conditional rendering checks into the JSX returned by `map`, improving performance and readability. - Removed redundant code segments and consolidated duplicate logic for handling binary value conditions within form inputs. These changes aim to enhance the maintainability of the codebase, improve the component's performance, and ensure a consistent user experience across different themes. --- src/components/TableEntry.jsx | 203 ++++++++++++---------------------- src/index.css | 2 +- 2 files changed, 71 insertions(+), 134 deletions(-) diff --git a/src/components/TableEntry.jsx b/src/components/TableEntry.jsx index e117af71..26a88df6 100644 --- a/src/components/TableEntry.jsx +++ b/src/components/TableEntry.jsx @@ -1,21 +1,21 @@ import { useEffect, useState, forwardRef } from 'react'; import { useAtomValue } from 'jotai'; -import { currentTableName } from '../utils/jotai' +import { currentTableName } from '../utils/jotai'; import { AnimatePresence, motion } from 'framer-motion'; import { tableRows } from '../utils/variants'; import { CheckIcon, DeleteIcon, EditIcon, XIcon } from '../assets/icons'; -import { getKey, getKeys, getLabel, TABLE_LABELS } from '../const/tableLabels'; +import { getKey, getKeys, getLabel } from '../const/tableLabels'; import { getSessionEntryCount, startEntryOperation } from '../utils/firestore'; import { Type, notify } from './Notifier'; import { FormField } from './FormFields'; -import { isNumber } from '@syncfusion/ej2-react-spreadsheet'; + +const BINARY_KEYS = ['noCaptures', 'isAlive', 'dead']; +const TRUE_KEYS = ['Y', 'y', 'T', 't']; +const FALSE_KEYS = ['N', 'n', 'F', 'f']; export const getValue = (entry, column) => { - if (!entry._document.data.value.mapValue.fields[getKey(column, name)]) { - return 'N/A'; - } - return entry._document.data.value.mapValue.fields - [getKey(column, name)].stringValue; + const field = entry._document.data.value.mapValue.fields[getKey(column, name)]; + return field ? field.stringValue : 'N/A'; } export const TableEntry = forwardRef((props, ref) => { @@ -28,62 +28,45 @@ export const TableEntry = forwardRef((props, ref) => { const [entryUIState, setEntryUIState] = useState('viewing'); const [entryData, setEntryData] = useState(entrySnapshot.data()); - const [keys, setKeys] = useState(); + const [keys, setKeys] = useState([]); const tableName = useAtomValue(currentTableName); - const [deleteMessage, setDeleteMessage] = useState('Are you sure you want to delete this row?') + const [deleteMessage, setDeleteMessage] = useState('Are you sure you want to delete this row?'); + useEffect(() => { + setKeys(getKeys(tableName)); + }, [tableName]); - const onEditClickedHandler = () => { - console.log('Edit clicked'); - setEntryUIState('editing'); - }; + const handleEditClick = () => setEntryUIState('editing'); - const onDeleteClickedHandler = async () => { + const handleDeleteClick = async () => { setEntryUIState('deleting'); if (entrySnapshot.ref.parent.id.includes('Session')) { const entryCount = await getSessionEntryCount(entrySnapshot); - setDeleteMessage(`Are you sure you want to delete this session and its ${entryCount} animal entries?`) + setDeleteMessage(`Are you sure you want to delete this session and its ${entryCount} animal entries?`); } }; - const onSaveClickedHandler = () => { - entryUIState === 'editing' && - startEntryOperation( - tableName.includes('Session') ? - 'uploadSessionEdits' - : - 'uploadEntryEdits', - { - entrySnapshot, - entryData, - setEntryUIState - } - ).then(response => notify(...response)); - entryUIState === 'deleting' && - startEntryOperation( - tableName.includes('Session') ? - 'deleteSession' - : - 'deleteEntry', - { - entrySnapshot, - removeEntryFromUI, - setEntryUIState - } - ).then(response => notify(...response)); + const handleSaveClick = () => { + const operationType = entryUIState === 'editing' + ? (tableName.includes('Session') ? 'uploadSessionEdits' : 'uploadEntryEdits') + : (tableName.includes('Session') ? 'deleteSession' : 'deleteEntry'); + + startEntryOperation(operationType, { + entrySnapshot, + entryData, + setEntryUIState, + removeEntryFromUI + }).then(response => notify(...response)); }; - const onCancelClickedHandler = () => { + const handleCancelClick = () => { setEntryData(entrySnapshot.data()); setEntryUIState('viewing'); }; - useEffect(() => { - setKeys(getKeys(tableName)); - }, []) - return ( - { ref={ref} > - {keys && keys.map((key) => ( + {keys.map(key => ( shownColumns.includes(getLabel(key)) && ( ) + /> + ) ))} ); }); const EntryItem = ({ entrySnapshot, dbKey, entryUIState, setEntryData, entryData }) => { - const [displayText, setDisplayText] = useState(entrySnapshot.data()[dbKey]); const [editable, setEditable] = useState(true); - const BINARY_KEYS = ['noCaptures', 'isAlive', 'dead']; - const TRUE_KEYS = ['Y', 'y', 'T', 't']; - const FALSE_KEYS = ['N', 'n', 'F', 'f']; - - const onChangeHandler = (e) => { - if (BINARY_KEYS.includes(dbKey)) { - if (TRUE_KEYS.includes(e.target.value.slice(-1))) { - setEntryData((prevEntryData) => ({ - ...prevEntryData, - [dbKey]: 'true', - })); - } else if (FALSE_KEYS.includes(e.target.value.slice(-1))) { - setEntryData((prevEntryData) => ({ - ...prevEntryData, - [dbKey]: 'false', - })); - } - } else { - setEntryData((prevEntryData) => ({ - ...prevEntryData, - [dbKey]: e.target.value, - })); - } - }; - - let disabled = false; + const handleChange = (e) => { + const value = e.target.value.slice(-1); + const isBinaryKey = BINARY_KEYS.includes(dbKey); + const isTrueKey = TRUE_KEYS.includes(value); + const isFalseKey = FALSE_KEYS.includes(value); - if ( - entryUIState === 'viewing' || - (entryUIState === 'editing' && !editable) || - entryUIState === 'deleting' - ) { - disabled = true; - } + setEntryData(prev => ({ + ...prev, + [dbKey]: isBinaryKey ? (isTrueKey ? 'true' : (isFalseKey ? 'false' : prev[dbKey])) : e.target.value, + })); + }; - let size = 1; - if (entrySnapshot.data()[dbKey] !== undefined) { - size = String(entrySnapshot.data()[dbKey]).length; - } + const disabled = entryUIState === 'viewing' || (entryUIState === 'editing' && !editable) || entryUIState === 'deleting'; + const size = entryData[dbKey] ? String(entryData[dbKey]).length : 1; return ( - + onChangeHandler(e)} + onChange={handleChange} size={size} /> @@ -172,10 +130,10 @@ const EntryItem = ({ entrySnapshot, dbKey, entryUIState, setEntryData, entryData }; const Actions = ({ - onEditClickedHandler, - onDeleteClickedHandler, - onSaveClickedHandler, - onCancelClickedHandler, + onEditClick, + onDeleteClick, + onSaveClick, + onCancelClick, entryUIState, deleteMessage }) => { @@ -187,56 +145,35 @@ const Actions = ({ {deleteMessage} )} - {entryUIState === 'viewing' && + {entryUIState === 'viewing' && ( <> -
onEditClickedHandler()}> +
-
onDeleteClickedHandler()}> +
- } - {(entryUIState === 'editing' || entryUIState === 'deleting') && + )} + {(entryUIState === 'editing' || entryUIState === 'deleting') && ( <> -
onSaveClickedHandler()}> +
-
onCancelClickedHandler()}> +
- } + + )}
- ) -} + ); +}; diff --git a/src/index.css b/src/index.css index 65ddddba..b58565f7 100644 --- a/src/index.css +++ b/src/index.css @@ -35,7 +35,7 @@ } select { - @apply cursor-pointer w-fit p-1.5 bg-neutral-200 dark:bg-neutral-800 dark:text-white rounded-md border-solid border-2 border-neutral-300 dark:border-neutral-500 focus:border-asu-gold h-10; + @apply cursor-pointer w-fit p-1.5 bg-neutral-200 dark:bg-neutral-800 text-black dark:text-white rounded-md border-solid border-2 border-neutral-300 dark:border-neutral-500 focus:border-asu-gold h-10; } input {