Skip to content

Commit

Permalink
fix: update module when the module in store is undefined
Browse files Browse the repository at this point in the history
Refs: SHELL-209 (#410)
  • Loading branch information
rodleyorosa authored May 20, 2024
1 parent cb6e9ce commit 7351433
Show file tree
Hide file tree
Showing 13 changed files with 574 additions and 210 deletions.
14 changes: 0 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 1 addition & 10 deletions src/history/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import type { To } from 'history';
import { find, startsWith, replace, trim } from 'lodash';
import { useLocation, useHistory } from 'react-router-dom';

import { SEARCH_APP_ID } from '../constants';
import { useSearchStore } from '../search/search-store';
import { useRoutes, getRoutes } from '../store/app';
import { useContextBridge } from '../store/context-bridge';
import type { AppRoute } from '../types/apps';
Expand All @@ -28,14 +26,7 @@ export const useCurrentRoute = (): AppRoute | undefined => {
export const getCurrentRoute = (): AppRoute | undefined => {
const history = useContextBridge.getState().functions.getHistory?.();
const routes = getRoutes();
const route = find(routes, (r) => startsWith(trim(history.location.pathname, '/'), r.route));
if (route?.route === SEARCH_APP_ID) {
return {
...route,
route: `${route.route}/${useSearchStore.getState().module}`
};
}
return route;
return find(routes, (r) => startsWith(trim(history.location.pathname, '/'), r.route));
};

export const parseParams = (params: HistoryParams): To => {
Expand Down
24 changes: 24 additions & 0 deletions src/search/module-selector.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* SPDX-FileCopyrightText: 2024 Zextras <https://www.zextras.com>
*
* SPDX-License-Identifier: AGPL-3.0-only
*/

import React from 'react';

import { screen } from '@testing-library/react';

import { ModuleSelector } from './module-selector';
import { useAppStore } from '../store/app';
import { TESTID_SELECTORS } from '../test/constants';
import { setup } from '../test/utils';

describe('Search module selector', () => {
it('should hide the component if there are no modules in the store', () => {
useAppStore.setState((state) => ({
views: { ...state.views, search: [] }
}));
setup(<ModuleSelector />);
expect(screen.queryByTestId(TESTID_SELECTORS.headerModuleSelector)).not.toBeInTheDocument();
});
});
53 changes: 25 additions & 28 deletions src/search/module-selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import type { DropdownItem } from '@zextras/carbonio-design-system';
import { Container, Row, Text, Icon, Dropdown } from '@zextras/carbonio-design-system';
import styled from 'styled-components';

import { useSearchStore } from './search-store';
import { useSearchModule } from './useSearchModule';
import { SEARCH_APP_ID } from '../constants';
import { useCurrentRoute, pushHistory } from '../history/hooks';
import { pushHistory, useCurrentRoute } from '../history/hooks';
import { useAppStore } from '../store/app';

const SelectorContainer = styled(Container)<{ open?: boolean }>`
Expand All @@ -24,42 +24,46 @@ const SelectorContainer = styled(Container)<{ open?: boolean }>`
}
`;

interface ModuleSelectorProps {
app: string | undefined;
}

const ModuleSelectorComponent = ({ app }: ModuleSelectorProps): React.JSX.Element | null => {
const modules = useAppStore((s) => s.views.search);
const { module, updateModule } = useSearchStore();

const fullModule = useMemo(
() => modules.find((m) => m.route === module) ?? modules[0],
[module, modules]
export const ModuleSelector = (): React.JSX.Element | null => {
const currentRoute = useCurrentRoute();
const searchViews = useAppStore((s) => s.views.search);
const [module, updateModule] = useSearchModule();
const searchView = useMemo(
() => searchViews.find((m) => m.route === module),
[module, searchViews]
);

const [open, setOpen] = useState(false);

const dropdownItems = useMemo(
(): DropdownItem[] =>
modules.map(
searchViews.map(
({ id, label, icon, route }): DropdownItem => ({
id,
label,
icon,
onClick: (): void => {
// open the search view and update the module of moduleSelector
// order is important
pushHistory({ route: SEARCH_APP_ID, path: '' });
updateModule(route);
pushHistory({ route: SEARCH_APP_ID, path: `/${route}` });
}
})
),
[modules, updateModule]
[searchViews, updateModule]
);

useEffect(() => {
if (app !== SEARCH_APP_ID && (!fullModule || fullModule?.app !== app)) {
updateModule((modules.find((m) => m.app === app) ?? modules[0])?.route);
// update the search module based on active route
// it handles also back navigation that cannot be handled using primary icon clicks
if (
currentRoute?.route &&
module !== currentRoute.route &&
searchViews.find((m) => m.route === currentRoute.route)
) {
updateModule(currentRoute.route);
}
}, [app, fullModule, modules, updateModule]);
}, [searchView, module, searchViews, updateModule, currentRoute?.route]);

const openDropdown = useCallback(() => {
setOpen(true);
Expand All @@ -69,7 +73,7 @@ const ModuleSelectorComponent = ({ app }: ModuleSelectorProps): React.JSX.Elemen
setOpen(false);
}, []);

if (!fullModule) {
if (!searchView) {
return null;
}

Expand All @@ -88,7 +92,7 @@ const ModuleSelectorComponent = ({ app }: ModuleSelectorProps): React.JSX.Elemen
>
<Row takeAvailableSpace mainAlignment="unset" padding={{ left: 'small' }}>
<Text size="small" color={open ? 'primary' : 'text'}>
{fullModule?.label}
{searchView?.label}
</Text>
</Row>
<Icon
Expand All @@ -101,10 +105,3 @@ const ModuleSelectorComponent = ({ app }: ModuleSelectorProps): React.JSX.Elemen
</Dropdown>
);
};

const MemoModuleSelector = React.memo(ModuleSelectorComponent);

export const ModuleSelector = (): React.JSX.Element => {
const activeRoute = useCurrentRoute();
return <MemoModuleSelector app={activeRoute?.app} />;
};
2 changes: 1 addition & 1 deletion src/search/run-search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ import type { QueryChip } from '../types/search';

export const runSearch = (query: Array<QueryChip>, module: string): void => {
useSearchStore.setState({ query, module, searchDisabled: false });
pushHistory({ route: SEARCH_APP_ID, path: `/${module}` });
pushHistory({ route: SEARCH_APP_ID, path: '' });
};
46 changes: 17 additions & 29 deletions src/search/search-app-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import {
Text
} from '@zextras/carbonio-design-system';
import { map } from 'lodash';
import { Redirect, Route, Switch } from 'react-router-dom';

import { useSearchStore } from './search-store';
import { useSearchModule } from './useSearchModule';
import AppContextProvider from '../boot/app/app-context-provider';
import { RESULT_LABEL_TYPE, SEARCH_APP_ID } from '../constants';
import { RESULT_LABEL_TYPE } from '../constants';
import { useAppStore } from '../store/app';
import { getT } from '../store/i18n/hooks';
import { type SearchState } from '../types/search';
Expand Down Expand Up @@ -125,36 +125,24 @@ const ResultsHeader = ({

export const SearchAppView = (): React.JSX.Element => {
const searchViews = useAppStore((s) => s.views.search);
const { module } = useSearchStore();
const modules = useAppStore((s) => s.views.search);
const [module] = useSearchModule();

const fullModule = useMemo(() => modules.find((m) => m.route === module), [module, modules]);

const routes = useMemo(
() =>
map(searchViews, (view) => (
<Route key={`/${view.route}`} path={`/${SEARCH_APP_ID}/${view.route}`}>
<AppContextProvider pkg={view.app}>
<view.component
useQuery={useQuery}
ResultsHeader={ResultsHeader}
useDisableSearch={useDisableSearch}
/>
</AppContextProvider>
</Route>
)),
[searchViews]
const searchView = useMemo(
() => searchViews.find((m) => m.route === module),
[module, searchViews]
);

return (
<Switch>
{routes}
<Redirect
exact
strict
from={`/${SEARCH_APP_ID}`}
to={`/${SEARCH_APP_ID}/${fullModule ? fullModule.route : searchViews[0]?.route}`}
/>
</Switch>
<>
{searchView && (
<AppContextProvider pkg={searchView.app}>
<searchView.component
useQuery={useQuery}
ResultsHeader={ResultsHeader}
useDisableSearch={useDisableSearch}
/>
</AppContextProvider>
)}
</>
);
};
Loading

0 comments on commit 7351433

Please sign in to comment.