324 add search records as a fallback action in case of no results (#9976)
Closes https://github.com/twentyhq/core-team-issues/issues/324 Fixed typos: 'No results' is used when multiple results are expected and 'No result' is used when only one result is expected. https://github.com/user-attachments/assets/e3655ced-465a-44b1-92af-63878b9d8a94
This commit is contained in:
@ -32,6 +32,7 @@ export const CommandMenu = () => {
|
||||
matchingStandardActionGlobalCommands,
|
||||
matchingWorkflowRunGlobalCommands,
|
||||
matchingNavigateCommands,
|
||||
fallbackCommands,
|
||||
} = useMatchingCommandMenuCommands({
|
||||
commandMenuSearch,
|
||||
});
|
||||
@ -44,6 +45,7 @@ export const CommandMenu = () => {
|
||||
matchingStandardActionGlobalCommands,
|
||||
matchingWorkflowRunGlobalCommands,
|
||||
matchingNavigateCommands,
|
||||
fallbackCommands,
|
||||
)
|
||||
.filter(isDefined);
|
||||
|
||||
@ -79,6 +81,10 @@ export const CommandMenu = () => {
|
||||
.concat(matchingNavigateCommands)
|
||||
.concat(matchingWorkflowRunGlobalCommands),
|
||||
},
|
||||
{
|
||||
heading: t`Search ''${commandMenuSearch}'' with...`,
|
||||
items: fallbackCommands,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
|
||||
@ -111,9 +111,6 @@ export const CommandMenuList = ({
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
{noResults && !loading && (
|
||||
<StyledEmpty>No result found</StyledEmpty>
|
||||
)}
|
||||
{commandGroups.map(({ heading, items }) =>
|
||||
items?.length ? (
|
||||
<CommandGroup heading={heading} key={heading}>
|
||||
@ -139,6 +136,9 @@ export const CommandMenuList = ({
|
||||
</CommandGroup>
|
||||
) : null,
|
||||
)}
|
||||
{noResults && !loading && (
|
||||
<StyledEmpty>No results found</StyledEmpty>
|
||||
)}
|
||||
</SelectableList>
|
||||
</StyledInnerList>
|
||||
</ScrollWrapper>
|
||||
|
||||
@ -8,7 +8,6 @@ import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWith
|
||||
import { ObjectMetadataItemsDecorator } from '~/testing/decorators/ObjectMetadataItemsDecorator';
|
||||
import { SnackBarDecorator } from '~/testing/decorators/SnackBarDecorator';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { getCompaniesMock } from '~/testing/mock-data/companies';
|
||||
import {
|
||||
mockCurrentWorkspace,
|
||||
mockedWorkspaceMemberData,
|
||||
@ -20,14 +19,16 @@ import { CommandMenuRouter } from '@/command-menu/components/CommandMenuRouter';
|
||||
import { isCommandMenuOpenedState } from '@/command-menu/states/isCommandMenuOpenedState';
|
||||
import { ContextStoreComponentInstanceContext } from '@/context-store/states/contexts/ContextStoreComponentInstanceContext';
|
||||
import { RecordFiltersComponentInstanceContext } from '@/object-record/record-filter/states/context/RecordFiltersComponentInstanceContext';
|
||||
import { HttpResponse, graphql } from 'msw';
|
||||
import { I18nFrontDecorator } from '~/testing/decorators/I18nFrontDecorator';
|
||||
import { JestContextStoreSetter } from '~/testing/jest/JestContextStoreSetter';
|
||||
import { getCompaniesMock } from '~/testing/mock-data/companies';
|
||||
import { CommandMenu } from '../CommandMenu';
|
||||
|
||||
const companiesMock = getCompaniesMock();
|
||||
|
||||
const openTimeout = 50;
|
||||
|
||||
const companiesMock = getCompaniesMock();
|
||||
|
||||
const ContextStoreDecorator: Decorator = (Story) => {
|
||||
return (
|
||||
<RecordFiltersComponentInstanceContext.Provider
|
||||
@ -125,6 +126,45 @@ export const SearchRecordsAction: Story = {
|
||||
expect(await canvas.findByText('Linkedin')).toBeVisible();
|
||||
const companyTexts = await canvas.findAllByText('Company');
|
||||
expect(companyTexts[0]).toBeVisible();
|
||||
expect(await canvas.findByText(companiesMock[0].name)).toBeVisible();
|
||||
},
|
||||
};
|
||||
|
||||
export const NoResultsSearchFallback: Story = {
|
||||
play: async () => {
|
||||
const canvas = within(document.body);
|
||||
const searchInput = await canvas.findByPlaceholderText('Type anything');
|
||||
await sleep(openTimeout);
|
||||
await userEvent.type(searchInput, 'Linkedin');
|
||||
expect(await canvas.findByText('No results found')).toBeVisible();
|
||||
const searchRecordsButton = await canvas.findByText('Search records');
|
||||
expect(searchRecordsButton).toBeVisible();
|
||||
await userEvent.click(searchRecordsButton);
|
||||
expect(await canvas.findByText('Linkedin')).toBeVisible();
|
||||
},
|
||||
parameters: {
|
||||
msw: {
|
||||
handlers: [
|
||||
graphql.query('CombinedSearchRecords', () => {
|
||||
return HttpResponse.json({
|
||||
data: {
|
||||
searchCompanies: {
|
||||
edges: [
|
||||
{
|
||||
node: companiesMock[0],
|
||||
cursor: null,
|
||||
},
|
||||
],
|
||||
pageInfo: {
|
||||
hasNextPage: false,
|
||||
hasPreviousPage: false,
|
||||
startCursor: null,
|
||||
endCursor: null,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user