diff --git a/packages/react-storage/src/components/StorageBrowser/composables/Search.tsx b/packages/react-storage/src/components/StorageBrowser/composables/Search.tsx index 0b8a9e3c383..0b717f730f4 100644 --- a/packages/react-storage/src/components/StorageBrowser/composables/Search.tsx +++ b/packages/react-storage/src/components/StorageBrowser/composables/Search.tsx @@ -74,13 +74,13 @@ export const Search = ({ {showIncludeSubfolders ? ( - setSubfoldersIncluded(!subfoldersIncluded)} - type="checkbox" - /> + setSubfoldersIncluded(!subfoldersIncluded)} + type="checkbox" + /> Include subfolders diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationActionView/__tests__/CopyFilesControls.spec.tsx b/packages/react-storage/src/components/StorageBrowser/views/LocationActionView/__tests__/CopyFilesControls.spec.tsx index 93620386fda..8dfa93dc24f 100644 --- a/packages/react-storage/src/components/StorageBrowser/views/LocationActionView/__tests__/CopyFilesControls.spec.tsx +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationActionView/__tests__/CopyFilesControls.spec.tsx @@ -1,10 +1,12 @@ import React from 'react'; import { render } from '@testing-library/react'; -import * as UseCopyViewModule from '../CopyView/useCopyView'; -import * as Config from '../../../providers/configuration'; - import userEvent from '@testing-library/user-event'; + +import * as AmplifyReactCore from '@aws-amplify/ui-react-core'; + import * as TempActions from '../../../do-not-import-from-here/createTempActionsProvider'; +import * as UseCopyViewModule from '../CopyView/useCopyView'; +import * as Config from '../../../providers/configuration'; import { CopyFilesControls } from '../CopyFilesControls'; const TEST_ACTIONS = { @@ -15,6 +17,7 @@ const TEST_ACTIONS = { jest.spyOn(TempActions, 'useTempActions').mockReturnValue(TEST_ACTIONS); const useCopyViewSpy = jest.spyOn(UseCopyViewModule, 'useCopyView'); +const useDataSpy = jest.spyOn(AmplifyReactCore, 'useDataState'); describe('CopyFilesControls', () => { const onExitMock = jest.fn(); @@ -22,6 +25,21 @@ describe('CopyFilesControls', () => { const onActionStartMock = jest.fn(); const onSetDestinationList = jest.fn(); + beforeAll(() => { + useDataSpy.mockReturnValue([ + { + data: { + items: [{ id: '1', key: 'Location A', type: 'FOLDER' }], + nextToken: undefined, + }, + message: '', + hasError: false, + isLoading: false, + }, + jest.fn(), + ]); + }); + beforeEach(() => { jest.clearAllMocks(); useCopyViewSpy.mockReturnValue({ @@ -98,8 +116,9 @@ describe('CopyFilesControls', () => { }); it('renders all controls', () => { - const { getByRole } = render(); + const { getByRole, getByPlaceholderText } = render(); + expect(getByPlaceholderText('Search for folders')).toBeInTheDocument(); expect(getByRole('button', { name: 'Exit' })).toBeInTheDocument(); expect(getByRole('button', { name: 'Start' })).toBeInTheDocument(); expect(getByRole('button', { name: 'Cancel' })).toBeInTheDocument(); diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/LocationDetailView.tsx b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/LocationDetailView.tsx index d7ebcc379af..cb46a9fa41e 100644 --- a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/LocationDetailView.tsx +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/LocationDetailView.tsx @@ -78,6 +78,8 @@ export function LocationDetailView({ hasError, message, shouldShowEmptyMessage, + searchPlaceholder, + showIncludeSubfolders, onDropFiles, onRefresh, onPaginate, @@ -86,6 +88,7 @@ export function LocationDetailView({ onNavigateHome, onSelect, onSelectAll, + onSearch, } = useLocationDetailView({ onNavigate: onNavigateProp, onExit }); return ( @@ -98,6 +101,8 @@ export function LocationDetailView({ isDataRefreshDisabled: isLoading, currentLocation, currentPath, + searchPlaceholder, + showIncludeSubfolders, tableData: getLocationDetailViewTableData({ areAllFilesSelected, currentLocation, @@ -115,6 +120,7 @@ export function LocationDetailView({ onNavigate={onNavigate} onNavigateHome={onNavigateHome} onRefresh={onRefresh} + onSearch={onSearch} > { expect(messageText).toBeInTheDocument(); }); + it('allows searching for items', async () => { + useStoreSpy.mockReturnValueOnce([ + { + location: { current: location, path: '', key: location.prefix }, + locationItems: { fileDataItems: undefined }, + } as StoreModule.UseStoreState, + dispatchStoreAction, + ]); + mockListItemsAction({ result: testResult }); + + const { getByPlaceholderText, getByText } = render(); + + const input = getByPlaceholderText('Search current folder'); + const subfolderOption = getByText('Include subfolders'); + + expect(input).toBeInTheDocument(); + expect(subfolderOption).toBeInTheDocument(); + + input.focus(); + await act(async () => { + await user.keyboard('boo'); + await user.click(getByText('Submit')); + }); + + expect(handleList).toHaveBeenCalledWith( + expect.objectContaining({ + options: expect.objectContaining({ + search: { + filterKey: 'key', + query: 'boo', + }, + }), + }) + ); + }); + it('loads initial location items for a BUCKET location as expected', () => { useStoreSpy.mockReturnValueOnce([ { diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/constants.ts b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/constants.ts new file mode 100644 index 00000000000..c61327d023d --- /dev/null +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/constants.ts @@ -0,0 +1,10 @@ +import { LocationDetailViewHeaders } from './types'; + +export const LOCATION_DETAIL_VIEW_HEADERS: LocationDetailViewHeaders = [ + { key: 'checkbox', type: 'text', content: { text: '' } }, + { key: 'name', type: 'sort', content: { label: 'Name' } }, + { key: 'type', type: 'sort', content: { label: 'Type' } }, + { key: 'last-modified', type: 'sort', content: { label: 'Last Modified' } }, + { key: 'size', type: 'sort', content: { label: 'Size' } }, + { key: 'download', type: 'text', content: { text: '' } }, +]; diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFileRowContent.ts b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFileRowContent.ts index c9f3a808c6b..b2e5b1d466b 100644 --- a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFileRowContent.ts +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFileRowContent.ts @@ -1,9 +1,11 @@ +import { humanFileSize } from '@aws-amplify/ui'; + import { DataTableProps } from '../../../composables/DataTable'; import { LocationData } from '../../../actions'; -import { LOCATION_DETAIL_VIEW_HEADERS } from './getLocationDetailViewTableData'; -import { humanFileSize } from '@aws-amplify/ui'; import { displayText } from '../../../displayText/en'; +import { LOCATION_DETAIL_VIEW_HEADERS } from './constants'; + export const getFileRowContent = ({ currentLocation, currentPath, diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.ts b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.ts index 1eede4ca725..e6809607c15 100644 --- a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.ts +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getFolderRowContent.ts @@ -1,5 +1,5 @@ import { DataTableProps } from '../../../composables/DataTable'; -import { LOCATION_DETAIL_VIEW_HEADERS } from './getLocationDetailViewTableData'; +import { LOCATION_DETAIL_VIEW_HEADERS } from './constants'; export const getFolderRowContent = ({ itemSubPath, diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.ts b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.ts index 2ccf13bc2d2..26a6f3e9dc3 100644 --- a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.ts +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/getLocationDetailViewTableData.ts @@ -1,31 +1,12 @@ -import { WithKey } from '../../../components/types'; import { DataTableProps } from '../../../composables/DataTable'; import { LocationData } from '../../../actions'; -import { LocationItemData } from '../../../../../../dist/types/components/StorageBrowser/actions'; +import { LocationItemData } from '../../../actions/handlers'; import { getFileRowContent } from './getFileRowContent'; import { getFolderRowContent } from './getFolderRowContent'; import { displayText } from '../../../displayText/en'; import { FileData } from '../../../actions/handlers'; -type HeaderKeys = - | 'checkbox' - | 'name' - | 'type' - | 'last-modified' - | 'size' - | 'download'; - -export const LOCATION_DETAIL_VIEW_HEADERS: WithKey< - DataTableProps['headers'][number], - HeaderKeys ->[] = [ - { key: 'checkbox', type: 'text', content: { text: '' } }, - { key: 'name', type: 'sort', content: { label: 'Name' } }, - { key: 'type', type: 'sort', content: { label: 'Type' } }, - { key: 'last-modified', type: 'sort', content: { label: 'Last Modified' } }, - { key: 'size', type: 'sort', content: { label: 'Size' } }, - { key: 'download', type: 'text', content: { text: '' } }, -]; +import { LOCATION_DETAIL_VIEW_HEADERS } from './constants'; export const getLocationDetailViewTableData = ({ areAllFilesSelected, diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/types.ts b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/types.ts new file mode 100644 index 00000000000..adcee7dc2db --- /dev/null +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationDetailView/getLocationDetailViewTableData/types.ts @@ -0,0 +1,15 @@ +import { DataTableProps } from '../../../composables/DataTable'; +import { WithKey } from '../../../components/types'; + +export type HeaderKeys = + | 'checkbox' + | 'name' + | 'type' + | 'last-modified' + | 'size' + | 'download'; + +export type LocationDetailViewHeaders = WithKey< + DataTableProps['headers'][number], + HeaderKeys +>[]; diff --git a/packages/react-storage/src/components/StorageBrowser/views/LocationsView/__tests__/LocationsView.spec.tsx b/packages/react-storage/src/components/StorageBrowser/views/LocationsView/__tests__/LocationsView.spec.tsx index a88d7061c99..f5d81f61a74 100644 --- a/packages/react-storage/src/components/StorageBrowser/views/LocationsView/__tests__/LocationsView.spec.tsx +++ b/packages/react-storage/src/components/StorageBrowser/views/LocationsView/__tests__/LocationsView.spec.tsx @@ -301,4 +301,26 @@ describe('LocationsListView', () => { }, }); }); + + it('allows searching for items', async () => { + const user = userEvent.setup(); + const { getByPlaceholderText, getByText, queryByText } = render( + + ); + + const input = getByPlaceholderText('Filter folders and files'); + + expect(input).toBeInTheDocument(); + expect(queryByText('item-0/')).toBeInTheDocument(); + expect(queryByText('item-1/')).toBeInTheDocument(); + + input.focus(); + await act(async () => { + await user.keyboard('item-0'); + await user.click(getByText('Submit')); + }); + + expect(queryByText('item-0/')).toBeInTheDocument(); + expect(queryByText('item-1/')).not.toBeInTheDocument(); + }); });