From 69b4b637f1b6cfab3cc4c7b4e6f642bdc38d73bc Mon Sep 17 00:00:00 2001 From: Jamie Howard Date: Tue, 22 Nov 2022 13:58:28 +0000 Subject: [PATCH] chore(upload): feedback feat(helper-plugin): persist upload localstroage --- .../helper-plugin/lib/src/utils/auth/index.js | 8 +++++ .../AssetDialog/BrowseStep/index.js | 17 +++++----- .../tests/__snapshots__/index.test.js.snap | 3 +- .../BrowseStep/tests/index.test.js | 34 ++++++++++++++----- packages/core/upload/admin/src/constants.js | 5 +++ .../admin/src/pages/App/MediaLibrary.js | 12 ++----- .../src/pages/App/tests/MediaLibrary.test.js | 34 ++++++++++++++----- 7 files changed, 75 insertions(+), 38 deletions(-) diff --git a/packages/core/helper-plugin/lib/src/utils/auth/index.js b/packages/core/helper-plugin/lib/src/utils/auth/index.js index cfd4cbe6f0..9bd494e169 100644 --- a/packages/core/helper-plugin/lib/src/utils/auth/index.js +++ b/packages/core/helper-plugin/lib/src/utils/auth/index.js @@ -1,5 +1,6 @@ // TODO @soupette we need to refactor this file +import { isNil } from 'lodash'; import isEmpty from 'lodash/isEmpty'; const TOKEN_KEY = 'jwtToken'; @@ -8,6 +9,8 @@ const CURRENT_STEP = 'GUIDED_TOUR_CURRENT_STEP'; const COMPLETED_STEPS = 'GUIDED_TOUR_COMPLETED_STEPS'; const SKIPPED = 'GUIDED_TOUR_SKIPPED'; const THEME_KEY = 'STRAPI_THEME'; // Also used in packages/core/admin/admin/src/components/ThemeToggleProvider/index.js +const UPLOAD_MODAL_VIEW = 'STRAPI_UPLOAD_MODAL_VIEW'; +const UPLOAD_VIEW = 'STRAPI_UPLOAD_LIBRARY_VIEW'; const parse = JSON.parse; const stringify = JSON.stringify; @@ -35,6 +38,8 @@ const auth = { const guidedTourState = auth.get(COMPLETED_STEPS); const guidedTourSkipped = parse(localStorage.getItem(SKIPPED)); const applicationTheme = localStorage.getItem(THEME_KEY); + const uploadMediaLibraryView = localStorage.getItem(UPLOAD_VIEW); + const uploadMediaLibraryModalView = localStorage.getItem(UPLOAD_MODAL_VIEW); localStorage.clear(); @@ -46,6 +51,9 @@ const auth = { localStorage.setItem(COMPLETED_STEPS, stringify(guidedTourState)); localStorage.setItem(SKIPPED, stringify(guidedTourSkipped)); localStorage.setItem(THEME_KEY, applicationTheme); + !isNil(uploadMediaLibraryView) && localStorage.setItem(UPLOAD_VIEW, uploadMediaLibraryView); + !isNil(uploadMediaLibraryModalView) && + localStorage.setItem(UPLOAD_MODAL_VIEW, uploadMediaLibraryModalView); } if (sessionStorage) { diff --git a/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/index.js b/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/index.js index 9374038c03..cf554dbb61 100644 --- a/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/index.js +++ b/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/index.js @@ -1,5 +1,4 @@ import React from 'react'; -import { toUpper } from 'lodash'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { useIntl } from 'react-intl'; @@ -19,7 +18,12 @@ import PlusIcon from '@strapi/icons/Plus'; import Grid from '@strapi/icons/Grid'; import List from '@strapi/icons/List'; -import { FolderDefinition, AssetDefinition, viewOptions } from '../../../constants'; +import { + FolderDefinition, + AssetDefinition, + viewOptions, + localStorageKeys, +} from '../../../constants'; import getTrad from '../../../utils/getTrad'; import { getBreadcrumbDataCM } from '../../../utils'; import getAllowedFiles from '../../../utils/getAllowedFiles'; @@ -34,7 +38,6 @@ import { Filters } from './Filters'; import PaginationFooter from './PaginationFooter'; import PageSize from './PageSize'; import SearchAsset from './SearchAsset'; -import pluginId from '../../../pluginId'; const StartBlockActions = styled(Flex)` & > * + * { @@ -54,7 +57,7 @@ const TypographyMaxWidth = styled(Typography)` const ActionContainer = styled(Box)` svg { path { - fill: ${({ theme }) => theme.colors.neutral900}; + fill: ${({ theme }) => theme.colors.neutral500}; } } `; @@ -82,10 +85,7 @@ export const BrowseStep = ({ selectedAssets, }) => { const { formatMessage } = useIntl(); - const [view, setView] = usePersistentState( - `STRAPI_${toUpper(pluginId)}_MODAL_VIEW`, - viewOptions.GRID - ); + const [view, setView] = usePersistentState(localStorageKeys.modalView, viewOptions.GRID); const isGridView = view === viewOptions.GRID; const { data: currentFolder, isLoading: isCurrentFolderLoading } = useFolder( @@ -156,7 +156,6 @@ export const BrowseStep = ({ : } label={ isGridView diff --git a/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/__snapshots__/index.test.js.snap b/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/__snapshots__/index.test.js.snap index 5d72ffda5c..dd0f830467 100644 --- a/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/__snapshots__/index.test.js.snap +++ b/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/__snapshots__/index.test.js.snap @@ -803,7 +803,7 @@ exports[`BrowseStep renders and match snapshot 1`] = ` } .c16 svg path { - fill: #212134; + fill: #8e8ea9; } @media (max-width:68.75rem) { @@ -915,7 +915,6 @@ exports[`BrowseStep renders and match snapshot 1`] = ` aria-disabled="false" aria-labelledby="tooltip-2" class="c4 c17" - data-testid="switch-to-list-view" tabindex="0" type="button" > diff --git a/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/index.test.js b/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/index.test.js index a0d353ed64..db9956a505 100644 --- a/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/index.test.js +++ b/packages/core/upload/admin/src/components/AssetDialog/BrowseStep/tests/index.test.js @@ -214,18 +214,34 @@ describe('BrowseStep', () => { expect(screen.getByText('Assets (1)')).toBeInTheDocument(); }); - it('displays the appropriate switch to change the view', () => { + describe('displays the appropriate switch to change the view', () => { const setView = jest.fn(); - usePersistentState.mockReturnValueOnce([viewOptions.GRID, setView]); - setup(); + it('Start with Grid View', () => { + usePersistentState.mockReturnValueOnce([viewOptions.GRID, setView]); + const { queryByRole } = setup(); - const listSwitch = screen.queryByTestId('switch-to-list-view'); - const gridSwitch = screen.queryByTestId('switch-to-grid-view'); + const listSwitch = queryByRole('button', { name: 'List View' }); + const gridSwitch = queryByRole('button', { name: 'Grid View' }); - expect(listSwitch).toBeInTheDocument(); - expect(gridSwitch).not.toBeInTheDocument(); + expect(listSwitch).toBeInTheDocument(); + expect(gridSwitch).not.toBeInTheDocument(); - fireEvent.click(listSwitch); - expect(setView).toHaveBeenCalledWith(viewOptions.LIST); + fireEvent.click(listSwitch); + expect(setView).toHaveBeenCalledWith(viewOptions.LIST); + }); + + it('Start with List View', () => { + usePersistentState.mockReturnValueOnce([viewOptions.LIST, setView]); + const { queryByRole } = setup(); + + const listSwitch = queryByRole('button', { name: 'List View' }); + const gridSwitch = queryByRole('button', { name: 'Grid View' }); + + expect(gridSwitch).toBeInTheDocument(); + expect(listSwitch).not.toBeInTheDocument(); + + fireEvent.click(gridSwitch); + expect(setView).toHaveBeenCalledWith(viewOptions.GRID); + }); }); }); diff --git a/packages/core/upload/admin/src/constants.js b/packages/core/upload/admin/src/constants.js index 961f76cfa4..f1bd59f909 100644 --- a/packages/core/upload/admin/src/constants.js +++ b/packages/core/upload/admin/src/constants.js @@ -168,3 +168,8 @@ export const sortOptions = [ { key: 'sort.updated_at_desc', value: 'updatedAt:DESC' }, { key: 'sort.updated_at_asc', value: 'updatedAt:ASC' }, ]; + +export const localStorageKeys = { + modalView: `STRAPI_UPLOAD_MODAL_VIEW`, + view: `STRAPI_UPLOAD_LIBRARY_VIEW`, +}; diff --git a/packages/core/upload/admin/src/pages/App/MediaLibrary.js b/packages/core/upload/admin/src/pages/App/MediaLibrary.js index a81e03d67c..153b7b34eb 100644 --- a/packages/core/upload/admin/src/pages/App/MediaLibrary.js +++ b/packages/core/upload/admin/src/pages/App/MediaLibrary.js @@ -2,7 +2,6 @@ import React, { useState, useRef } from 'react'; // useState import { useIntl } from 'react-intl'; import styled from 'styled-components'; import { useHistory, useLocation } from 'react-router-dom'; -import { toUpper } from 'lodash'; import { LoadingIndicatorPage, @@ -51,8 +50,7 @@ import { import { Filters } from './components/Filters'; import { Header } from './components/Header'; import { EmptyOrNoPermissions } from './components/EmptyOrNoPermissions'; -import { viewOptions } from '../../constants'; -import pluginId from '../../pluginId'; +import { localStorageKeys, viewOptions } from '../../constants'; const BoxWithHeight = styled(Box)` height: ${32 / 16}rem; @@ -67,7 +65,7 @@ const TypographyMaxWidth = styled(Typography)` const ActionContainer = styled(Box)` svg { path { - fill: ${({ theme }) => theme.colors.neutral900}; + fill: ${({ theme }) => theme.colors.neutral500}; } } `; @@ -87,10 +85,7 @@ export const MediaLibrary = () => { const { trackUsage } = useTracking(); const [{ query }, setQuery] = useQueryParams(); const isFiltering = Boolean(query._q || query.filters); - const [view, setView] = usePersistentState( - `STRAPI_${toUpper(pluginId)}_LIBRARY_VIEW`, - viewOptions.GRID - ); + const [view, setView] = usePersistentState(localStorageKeys.view, viewOptions.GRID); const isGridView = view === viewOptions.GRID; const { @@ -229,7 +224,6 @@ export const MediaLibrary = () => { <> : } label={ isGridView diff --git a/packages/core/upload/admin/src/pages/App/tests/MediaLibrary.test.js b/packages/core/upload/admin/src/pages/App/tests/MediaLibrary.test.js index 44fad639f0..a56976a5a3 100644 --- a/packages/core/upload/admin/src/pages/App/tests/MediaLibrary.test.js +++ b/packages/core/upload/admin/src/pages/App/tests/MediaLibrary.test.js @@ -501,19 +501,35 @@ describe('Media library homepage', () => { expect(screen.queryByText('header.actions.add-assets')).not.toBeInTheDocument(); }); - it('displays the appropriate switch to change the view', () => { + describe('displays the appropriate switch to change the view', () => { const setView = jest.fn(); - usePersistentState.mockReturnValueOnce([viewOptions.GRID, setView]); - renderML(); + it('Start with Grid View', () => { + usePersistentState.mockReturnValueOnce([viewOptions.GRID, setView]); + const { queryByRole } = renderML(); - const listSwitch = screen.queryByTestId('switch-to-list-view'); - const gridSwitch = screen.queryByTestId('switch-to-grid-view'); + const listSwitch = queryByRole('button', { name: 'List View' }); + const gridSwitch = queryByRole('button', { name: 'Grid View' }); - expect(listSwitch).toBeInTheDocument(); - expect(gridSwitch).not.toBeInTheDocument(); + expect(listSwitch).toBeInTheDocument(); + expect(gridSwitch).not.toBeInTheDocument(); - fireEvent.click(listSwitch); - expect(setView).toHaveBeenCalledWith(viewOptions.LIST); + fireEvent.click(listSwitch); + expect(setView).toHaveBeenCalledWith(viewOptions.LIST); + }); + + it('Start with List View', () => { + usePersistentState.mockReturnValueOnce([viewOptions.LIST, setView]); + const { queryByRole } = renderML(); + + const listSwitch = queryByRole('button', { name: 'List View' }); + const gridSwitch = queryByRole('button', { name: 'Grid View' }); + + expect(gridSwitch).toBeInTheDocument(); + expect(listSwitch).not.toBeInTheDocument(); + + fireEvent.click(gridSwitch); + expect(setView).toHaveBeenCalledWith(viewOptions.GRID); + }); }); }); });