mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	feat: move recording recently visited into separate component (#7494)
This commit is contained in:
		
							parent
							
								
									93eb642f2f
								
							
						
					
					
						commit
						20da40d38d
					
				@ -14,7 +14,6 @@ import { useKeyboardShortcut } from 'hooks/useKeyboardShortcut';
 | 
				
			|||||||
import { SEARCH_INPUT } from 'utils/testIds';
 | 
					import { SEARCH_INPUT } from 'utils/testIds';
 | 
				
			||||||
import { useOnClickOutside } from 'hooks/useOnClickOutside';
 | 
					import { useOnClickOutside } from 'hooks/useOnClickOutside';
 | 
				
			||||||
import { useOnBlur } from 'hooks/useOnBlur';
 | 
					import { useOnBlur } from 'hooks/useOnBlur';
 | 
				
			||||||
import { useRecentlyVisited } from 'hooks/useRecentlyVisited';
 | 
					 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
    CommandResultGroup,
 | 
					    CommandResultGroup,
 | 
				
			||||||
    type CommandResultGroupItem,
 | 
					    type CommandResultGroupItem,
 | 
				
			||||||
@ -27,6 +26,7 @@ import { CommandFeatures } from './CommandFeatures';
 | 
				
			|||||||
import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
 | 
					import { usePlausibleTracker } from 'hooks/usePlausibleTracker';
 | 
				
			||||||
import { CommandRecent } from './CommandRecent';
 | 
					import { CommandRecent } from './CommandRecent';
 | 
				
			||||||
import { CommandPages } from './CommandPages';
 | 
					import { CommandPages } from './CommandPages';
 | 
				
			||||||
 | 
					import { RecentlyVisitedRecorder } from './RecentlyVisitedRecorder';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CommandResultsPaper = styled(Paper)(({ theme }) => ({
 | 
					export const CommandResultsPaper = styled(Paper)(({ theme }) => ({
 | 
				
			||||||
    position: 'absolute',
 | 
					    position: 'absolute',
 | 
				
			||||||
@ -110,7 +110,6 @@ export const CommandBar = () => {
 | 
				
			|||||||
    >([]);
 | 
					    >([]);
 | 
				
			||||||
    const [searchedFlagCount, setSearchedFlagCount] = useState(0);
 | 
					    const [searchedFlagCount, setSearchedFlagCount] = useState(0);
 | 
				
			||||||
    const [value, setValue] = useState<string>('');
 | 
					    const [value, setValue] = useState<string>('');
 | 
				
			||||||
    const { lastVisited } = useRecentlyVisited();
 | 
					 | 
				
			||||||
    const { routes } = useRoutes();
 | 
					    const { routes } = useRoutes();
 | 
				
			||||||
    const allRoutes: Record<string, IPageRouteInfo> = {};
 | 
					    const allRoutes: Record<string, IPageRouteInfo> = {};
 | 
				
			||||||
    for (const route of [
 | 
					    for (const route of [
 | 
				
			||||||
@ -200,6 +199,7 @@ export const CommandBar = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <StyledContainer ref={searchContainerRef} active={showSuggestions}>
 | 
					        <StyledContainer ref={searchContainerRef} active={showSuggestions}>
 | 
				
			||||||
 | 
					            <RecentlyVisitedRecorder />
 | 
				
			||||||
            <StyledSearch>
 | 
					            <StyledSearch>
 | 
				
			||||||
                <SearchIcon
 | 
					                <SearchIcon
 | 
				
			||||||
                    sx={{
 | 
					                    sx={{
 | 
				
			||||||
@ -266,10 +266,7 @@ export const CommandBar = () => {
 | 
				
			|||||||
                elseShow={
 | 
					                elseShow={
 | 
				
			||||||
                    showSuggestions && (
 | 
					                    showSuggestions && (
 | 
				
			||||||
                        <CommandResultsPaper>
 | 
					                        <CommandResultsPaper>
 | 
				
			||||||
                            <CommandRecent
 | 
					                            <CommandRecent routes={allRoutes} />
 | 
				
			||||||
                                lastVisited={lastVisited}
 | 
					 | 
				
			||||||
                                routes={allRoutes}
 | 
					 | 
				
			||||||
                            />
 | 
					 | 
				
			||||||
                            <CommandPageSuggestions routes={allRoutes} />
 | 
					                            <CommandPageSuggestions routes={allRoutes} />
 | 
				
			||||||
                        </CommandResultsPaper>
 | 
					                        </CommandResultsPaper>
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,10 @@ import {
 | 
				
			|||||||
    RecentlyVisitedProjectButton,
 | 
					    RecentlyVisitedProjectButton,
 | 
				
			||||||
} from './RecentlyVisited/CommandResultGroup';
 | 
					} from './RecentlyVisited/CommandResultGroup';
 | 
				
			||||||
import { List } from '@mui/material';
 | 
					import { List } from '@mui/material';
 | 
				
			||||||
import type { LastViewedPage } from 'hooks/useRecentlyVisited';
 | 
					import {
 | 
				
			||||||
 | 
					    useRecentlyVisited,
 | 
				
			||||||
 | 
					    type LastViewedPage,
 | 
				
			||||||
 | 
					} from 'hooks/useRecentlyVisited';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const toListItemButton = (
 | 
					const toListItemButton = (
 | 
				
			||||||
    item: LastViewedPage,
 | 
					    item: LastViewedPage,
 | 
				
			||||||
@ -38,12 +41,11 @@ const toListItemButton = (
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CommandRecent = ({
 | 
					export const CommandRecent = ({
 | 
				
			||||||
    lastVisited,
 | 
					 | 
				
			||||||
    routes,
 | 
					    routes,
 | 
				
			||||||
}: {
 | 
					}: {
 | 
				
			||||||
    lastVisited: LastViewedPage[];
 | 
					 | 
				
			||||||
    routes: Record<string, { path: string; route: string; title: string }>;
 | 
					    routes: Record<string, { path: string; route: string; title: string }>;
 | 
				
			||||||
}) => {
 | 
					}) => {
 | 
				
			||||||
 | 
					    const { lastVisited } = useRecentlyVisited();
 | 
				
			||||||
    const buttons = lastVisited.map((item, index) =>
 | 
					    const buttons = lastVisited.map((item, index) =>
 | 
				
			||||||
        toListItemButton(item, routes, index),
 | 
					        toListItemButton(item, routes, index),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					import { useRecentlyVisited } from 'hooks/useRecentlyVisited';
 | 
				
			||||||
 | 
					import { useLocation, useMatch } from 'react-router-dom';
 | 
				
			||||||
 | 
					import { routes } from 'component/menu/routes';
 | 
				
			||||||
 | 
					import { useEffect } from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const RecentlyVisitedRecorder = () => {
 | 
				
			||||||
 | 
					    const { setLastVisited } = useRecentlyVisited();
 | 
				
			||||||
 | 
					    const featureMatch = useMatch('/projects/:projectId/features/:featureId');
 | 
				
			||||||
 | 
					    const projectMatch = useMatch('/projects/:projectId');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const location = useLocation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    useEffect(() => {
 | 
				
			||||||
 | 
					        if (!location.pathname) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const path = routes.find((r) => r.path === location.pathname);
 | 
				
			||||||
 | 
					        if (path) {
 | 
				
			||||||
 | 
					            setLastVisited({ pathName: path.path });
 | 
				
			||||||
 | 
					        } else if (featureMatch?.params.featureId) {
 | 
				
			||||||
 | 
					            setLastVisited({
 | 
				
			||||||
 | 
					                featureId: featureMatch?.params.featureId,
 | 
				
			||||||
 | 
					                projectId: featureMatch?.params.projectId,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } else if (projectMatch?.params.projectId) {
 | 
				
			||||||
 | 
					            setLastVisited({
 | 
				
			||||||
 | 
					                projectId: projectMatch?.params.projectId,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }, [location, featureMatch, projectMatch]);
 | 
				
			||||||
 | 
					    return <></>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -9,11 +9,13 @@ import {
 | 
				
			|||||||
    createMemoryRouter,
 | 
					    createMemoryRouter,
 | 
				
			||||||
} from 'react-router-dom';
 | 
					} from 'react-router-dom';
 | 
				
			||||||
import { useRecentlyVisited } from './useRecentlyVisited';
 | 
					import { useRecentlyVisited } from './useRecentlyVisited';
 | 
				
			||||||
 | 
					import { RecentlyVisitedRecorder } from 'component/commandBar/RecentlyVisitedRecorder';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const RouteNameRender: FC<{}> = () => {
 | 
					const RouteNameRender: FC<{}> = () => {
 | 
				
			||||||
    const { lastVisited } = useRecentlyVisited();
 | 
					    const { lastVisited } = useRecentlyVisited();
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div>
 | 
					        <div>
 | 
				
			||||||
 | 
					            <RecentlyVisitedRecorder />
 | 
				
			||||||
            {lastVisited.map((visited) => (
 | 
					            {lastVisited.map((visited) => (
 | 
				
			||||||
                <div>{visited.pathName}</div>
 | 
					                <div>{visited.pathName}</div>
 | 
				
			||||||
            ))}
 | 
					            ))}
 | 
				
			||||||
@ -34,14 +36,22 @@ test('checks that routes that exist in routes.ts gets added to lastVisited', asy
 | 
				
			|||||||
                <Route path='/search' element={<Navigate to={'/unknown1'} />} />
 | 
					                <Route path='/search' element={<Navigate to={'/unknown1'} />} />
 | 
				
			||||||
                <Route
 | 
					                <Route
 | 
				
			||||||
                    path='/unknown1'
 | 
					                    path='/unknown1'
 | 
				
			||||||
                    element={<Navigate to={'/integrations'} />}
 | 
					 | 
				
			||||||
                />
 | 
					 | 
				
			||||||
                <Route
 | 
					 | 
				
			||||||
                    path='/integrations'
 | 
					 | 
				
			||||||
                    element={<Navigate to={'/unknown2'} />}
 | 
					                    element={<Navigate to={'/unknown2'} />}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
                <Route
 | 
					                <Route
 | 
				
			||||||
                    path='/unknown2'
 | 
					                    path='/unknown2'
 | 
				
			||||||
 | 
					                    element={<Navigate to={'/integrations'} />}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					                <Route
 | 
				
			||||||
 | 
					                    path='/integrations'
 | 
				
			||||||
 | 
					                    element={<Navigate to={'/unknown3'} />}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					                <Route
 | 
				
			||||||
 | 
					                    path='/unknown3'
 | 
				
			||||||
 | 
					                    element={<Navigate to={'/unknown4'} />}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					                <Route
 | 
				
			||||||
 | 
					                    path='/unknown4'
 | 
				
			||||||
                    element={<Navigate to={'/segments'} />}
 | 
					                    element={<Navigate to={'/segments'} />}
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
                <Route path='/segments' element={<div>segment div</div>} />
 | 
					                <Route path='/segments' element={<div>segment div</div>} />
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,4 @@
 | 
				
			|||||||
import { useCallback, useEffect, useState } from 'react';
 | 
					import { useCallback, useEffect, useState } from 'react';
 | 
				
			||||||
import { useLocation, useMatch } from 'react-router-dom';
 | 
					 | 
				
			||||||
import { routes } from 'component/menu/routes';
 | 
					 | 
				
			||||||
import { getLocalStorageItem, setLocalStorageItem } from '../utils/storage';
 | 
					import { getLocalStorageItem, setLocalStorageItem } from '../utils/storage';
 | 
				
			||||||
import { basePath } from 'utils/formatPath';
 | 
					import { basePath } from 'utils/formatPath';
 | 
				
			||||||
import { useCustomEvent } from './useCustomEvent';
 | 
					import { useCustomEvent } from './useCustomEvent';
 | 
				
			||||||
@ -20,8 +18,6 @@ const localStorageItems = (key: string): LastViewedPage[] => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export const useRecentlyVisited = () => {
 | 
					export const useRecentlyVisited = () => {
 | 
				
			||||||
    const key = `${basePath}:unleash-lastVisitedPages`;
 | 
					    const key = `${basePath}:unleash-lastVisitedPages`;
 | 
				
			||||||
    const featureMatch = useMatch('/projects/:projectId/features/:featureId');
 | 
					 | 
				
			||||||
    const projectMatch = useMatch('/projects/:projectId');
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const [lastVisited, setLastVisited] = useState<LastViewedPage[]>(
 | 
					    const [lastVisited, setLastVisited] = useState<LastViewedPage[]>(
 | 
				
			||||||
        localStorageItems(key),
 | 
					        localStorageItems(key),
 | 
				
			||||||
@ -34,26 +30,6 @@ export const useRecentlyVisited = () => {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const location = useLocation();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    useEffect(() => {
 | 
					 | 
				
			||||||
        if (!location.pathname) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const path = routes.find((r) => r.path === location.pathname);
 | 
					 | 
				
			||||||
        if (path) {
 | 
					 | 
				
			||||||
            setCappedLastVisited({ pathName: path.path });
 | 
					 | 
				
			||||||
        } else if (featureMatch?.params.featureId) {
 | 
					 | 
				
			||||||
            setCappedLastVisited({
 | 
					 | 
				
			||||||
                featureId: featureMatch?.params.featureId,
 | 
					 | 
				
			||||||
                projectId: featureMatch?.params.projectId,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        } else if (projectMatch?.params.projectId) {
 | 
					 | 
				
			||||||
            setCappedLastVisited({
 | 
					 | 
				
			||||||
                projectId: projectMatch?.params.projectId,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }, [location, featureMatch, projectMatch]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        if (lastVisited) {
 | 
					        if (lastVisited) {
 | 
				
			||||||
            setLocalStorageItem(key, lastVisited);
 | 
					            setLocalStorageItem(key, lastVisited);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user