From 46a21b7d926b70bdb48a25c1d481c5c15b5610f1 Mon Sep 17 00:00:00 2001 From: Guy McAuliffe <38873380+gmcauliffe@users.noreply.github.com> Date: Wed, 23 Oct 2024 11:43:19 -0700 Subject: [PATCH] FW-6190 media selector bug (#647) * Remove unused unselectItem function * Remove use of useModalSelector from AudioArrayField * Create custom modal hook that includes useFieldArray * Rename selectedTab to currentTab to reduce use of term selected * Rename savedMedia to formMedia for clarity * FW-6190 clear selected images when modal closes * Filter out existing related entries from search results --- src/common/hooks/useModalController.js | 37 +++-- .../AddAudioModal/AddAudioModalContainer.js | 31 ++-- .../AddImageModal/AddImageModalContainer.js | 31 ++-- .../AddMediaModalWrapper.js | 24 ++-- .../AddVideoModal/AddVideoModalContainer.js | 33 +++-- src/components/Form/AudioArrayField.js | 14 +- src/components/Form/AudioIdField.js | 6 +- src/components/Form/CategoryArrayField.js | 24 ++-- src/components/Form/EntryArrayField.js | 30 ++-- src/components/Form/ImageArrayField.js | 22 ++- src/components/Form/ImageIdField.js | 6 +- src/components/Form/SelectOneMedia.js | 8 +- src/components/Form/VideoArrayField.js | 21 ++- .../SelectorAudio/SelectorAudioContainer.js | 6 +- .../SelectorAudioPresentation.js | 10 +- .../SelectorEntry/SelectorEntryContainer.js | 15 +- .../SelectorEntryPresentationList.js | 132 ++++++++++-------- .../SelectorImages/SelectorImagesContainer.js | 6 +- .../SelectorVideos/SelectorVideosContainer.js | 6 +- .../SelectorVisualMediaGridPresentation.js | 10 +- 20 files changed, 254 insertions(+), 218 deletions(-) diff --git a/src/common/hooks/useModalController.js b/src/common/hooks/useModalController.js index bd1d04ec..cd8653f3 100644 --- a/src/common/hooks/useModalController.js +++ b/src/common/hooks/useModalController.js @@ -1,4 +1,7 @@ import { useState } from 'react' +import { useFieldArray } from 'react-hook-form' + +// FPCC function useModalController() { const [modalOpen, setModalOpen] = useState(false) @@ -18,29 +21,35 @@ export function useModalControllerWithCallback({ onCloseCallback = () => {} }) { modalOpen, openModal, closeModal, - closeWithCallback: () => { - onCloseCallback() + closeWithCallback: (params) => { + onCloseCallback(params) closeModal() }, } } -export function useModalSelector(addItems, removeItem) { +export function useModalWithFieldArray({ control, nameId }) { const { modalOpen, openModal, closeModal } = useModalController() - // Can be multiple ids for a list of documents - // or can be just one item's id - const selectItem = (ids, closeModalAfter = true) => { - addItems(ids) - if (closeModalAfter) { - closeModal() - } - } + const { fields, append, remove } = useFieldArray({ + control, + name: nameId, + keyName: 'key', // https://github.com/react-hook-form/react-hook-form/issues/7562#issuecomment-1016379084 + }) + + // Can be a single object or an array of objects + const appendToFormAndClose = (itemsToAppend) => { + append(itemsToAppend) - const unselectItem = (id) => { - removeItem(id) closeModal() } - return { selectItem, unselectItem, modalOpen, openModal, closeModal } + return { + fields, + appendToFormAndClose, + remove, + modalOpen, + openModal, + closeModal, + } } diff --git a/src/components/AddAudioModal/AddAudioModalContainer.js b/src/components/AddAudioModal/AddAudioModalContainer.js index e2b1eaee..dfe8f0b5 100644 --- a/src/components/AddAudioModal/AddAudioModalContainer.js +++ b/src/components/AddAudioModal/AddAudioModalContainer.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import PropTypes from 'prop-types' // FPCC @@ -9,8 +9,8 @@ import AddMediaModalWrapper from 'components/AddMediaModalWrapper' import { TYPE_AUDIO } from 'common/constants' function AddAudioModalContainer({ - savedMedia, - updateSavedMedia, + formMedia, + updateFormMedia, maxItems, modalOpen, closeModal, @@ -18,6 +18,13 @@ function AddAudioModalContainer({ const { selectedItems, setSelectedItems, handleSelectAdditionalItems } = useArrayStateManager({ maxItems }) + // Clear the Selected items when the modal closes + useEffect(() => { + if (!modalOpen) { + setSelectedItems([]) + } + }, [modalOpen, setSelectedItems]) + const tabOptions = [ { id: 'upload-tab', @@ -33,26 +40,26 @@ function AddAudioModalContainer({ }, ] - const [selectedTab, setSelectedTab] = useState(tabOptions[1]) + const [currentTab, setCurrentTab] = useState(tabOptions[1]) return ( <> - {selectedTab.id === 'upload-tab' && ( + {currentTab.id === 'upload-tab' && ( )} - {selectedTab.id === 'search-tab' && ( + {currentTab.id === 'search-tab' && ( @@ -65,8 +72,8 @@ function AddAudioModalContainer({ const { array, bool, func, number } = PropTypes AddAudioModalContainer.propTypes = { - savedMedia: array, - updateSavedMedia: func, + formMedia: array, + updateFormMedia: func, maxItems: number, closeModal: func, modalOpen: bool, diff --git a/src/components/AddImageModal/AddImageModalContainer.js b/src/components/AddImageModal/AddImageModalContainer.js index 04490b38..7bf94d77 100644 --- a/src/components/AddImageModal/AddImageModalContainer.js +++ b/src/components/AddImageModal/AddImageModalContainer.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import PropTypes from 'prop-types' // FPCC @@ -9,8 +9,8 @@ import useArrayStateManager from 'common/hooks/useArrayStateManager' import AddMediaModalWrapper from 'components/AddMediaModalWrapper' function AddImageModalContainer({ - savedMedia, - updateSavedMedia, + formMedia, + updateFormMedia, maxItems, modalOpen, closeModal, @@ -19,6 +19,13 @@ function AddImageModalContainer({ const { selectedItems, setSelectedItems, handleSelectAdditionalItems } = useArrayStateManager({ maxItems }) + // Clear the Selected items when the modal closes + useEffect(() => { + if (!modalOpen) { + setSelectedItems([]) + } + }, [modalOpen, setSelectedItems]) + const tabOptions = [ { id: 'upload-tab', @@ -34,30 +41,30 @@ function AddImageModalContainer({ }, ] - const [selectedTab, setSelectedTab] = useState(tabOptions[1]) + const [currentTab, setCurrentTab] = useState(tabOptions[1]) return ( <> - {selectedTab.id === 'upload-tab' && ( + {currentTab.id === 'upload-tab' && ( )} - {selectedTab.id === 'search-tab' && ( + {currentTab.id === 'search-tab' && ( { const itemsSelected = selectedMedia.length > 0 - const tabHasSelectedItems = itemsSelected && selectedTab.id === tab.id + const tabHasSelectedItems = itemsSelected && currentTab.id === tab.id // If no files are uploaded/selected, allow the user to switch tabs // otherwise switch to Insert Media button // allowing user to attach the selected/uploaded files to the document. const handleOnClick = () => { - if (tabHasSelectedItems) updateSavedMedia(selectedMedia) - setSelectedTab(tab) + if (tabHasSelectedItems) updateFormMedia(selectedMedia) + setCurrentTab(tab) } return ( - + ) + })} + + ))} + + +
+
- )} - + + )} ) } // PROPTYPES -const { arrayOf, func, object, string } = PropTypes +const { array, arrayOf, func, object, string } = PropTypes SelectorEntryPresentationList.propTypes = { addToEntry: func, + formEntries: array, searchResults: object, infiniteScroll: object, selected: object, diff --git a/src/components/SelectorImages/SelectorImagesContainer.js b/src/components/SelectorImages/SelectorImagesContainer.js index 43d111f5..ba744ec5 100644 --- a/src/components/SelectorImages/SelectorImagesContainer.js +++ b/src/components/SelectorImages/SelectorImagesContainer.js @@ -10,7 +10,7 @@ import { TYPE_IMAGE } from 'common/constants' import RadioButtonGroup from 'components/RadioButtonGroup' function SelectorImagesContainer({ - savedMedia, + formMedia, selectedMedia, mediaSelectHandler, hideSharedMedia = false, @@ -86,7 +86,7 @@ function SelectorImagesContainer({ data={media} infiniteScroll={infiniteScroll} loadLabel={loadLabel} - savedMedia={savedMedia} + formMedia={formMedia} selectedMedia={selectedMedia} mediaSelectHandler={mediaSelectHandler} /> @@ -102,7 +102,7 @@ function SelectorImagesContainer({ // PROPTYPES const { array, bool, func } = PropTypes SelectorImagesContainer.propTypes = { - savedMedia: array, + formMedia: array, selectedMedia: array, mediaSelectHandler: func, hideSharedMedia: bool, diff --git a/src/components/SelectorVideos/SelectorVideosContainer.js b/src/components/SelectorVideos/SelectorVideosContainer.js index e0bef24c..df9b49b3 100644 --- a/src/components/SelectorVideos/SelectorVideosContainer.js +++ b/src/components/SelectorVideos/SelectorVideosContainer.js @@ -9,7 +9,7 @@ import useMediaSearch from 'common/dataHooks/useMediaSearch' import { TYPE_VIDEO } from 'common/constants' function SelectorVideosContainer({ - savedMedia, + formMedia, selectedMedia, mediaSelectHandler, }) { @@ -53,7 +53,7 @@ function SelectorVideosContainer({ data={media} infiniteScroll={infiniteScroll} loadLabel={loadLabel} - savedMedia={savedMedia} + formMedia={formMedia} selectedMedia={selectedMedia} mediaSelectHandler={mediaSelectHandler} /> @@ -69,7 +69,7 @@ function SelectorVideosContainer({ // PROPTYPES const { array, func } = PropTypes SelectorVideosContainer.propTypes = { - savedMedia: array, + formMedia: array, selectedMedia: array, mediaSelectHandler: func, } diff --git a/src/components/SelectorVisualMediaGrid/SelectorVisualMediaGridPresentation.js b/src/components/SelectorVisualMediaGrid/SelectorVisualMediaGridPresentation.js index ba6cc1be..9adfe041 100644 --- a/src/components/SelectorVisualMediaGrid/SelectorVisualMediaGridPresentation.js +++ b/src/components/SelectorVisualMediaGrid/SelectorVisualMediaGridPresentation.js @@ -8,7 +8,7 @@ function SelectorVisualMediaGridPresentation({ data, infiniteScroll, loadLabel, - savedMedia, + formMedia, selectedMedia, mediaSelectHandler, }) { @@ -26,10 +26,8 @@ function SelectorVisualMediaGridPresentation({ data?.pages?.map((page) => ( {page.results.map((mediaObject) => { - if ( - savedMedia?.some((elem) => elem?.id === mediaObject?.id) - ) { - // If a media file is already attached to the document + if (formMedia?.some((elem) => elem?.id === mediaObject?.id)) { + // If a media file is already in the form // it will not be presented as a choice in the selectMedia dialog box return null } @@ -105,7 +103,7 @@ SelectorVisualMediaGridPresentation.propTypes = { data: object, infiniteScroll: object, loadLabel: string, - savedMedia: array, + formMedia: array, selectedMedia: array, mediaSelectHandler: func, }