Infinite scrolling in relation picker menu (#12051)

https://github.com/user-attachments/assets/4be785e0-ea8a-4c8e-840e-6fa0a663d7ba

Closes #11938

---------

Co-authored-by: martmull <martmull@hotmail.fr>
This commit is contained in:
Abdul Rahman
2025-05-23 20:53:09 +05:30
committed by GitHub
parent 6ef9a3b4c9
commit af5762c8ba
37 changed files with 1867 additions and 562 deletions

View File

@ -172,7 +172,13 @@ export const NoResultsSearchFallback: Story = {
graphql.query('Search', () => {
return HttpResponse.json({
data: {
search: [],
search: {
edges: [],
pageInfo: {
hasNextPage: false,
endCursor: null,
},
},
},
});
}),

View File

@ -1,9 +1,10 @@
import gql from 'graphql-tag';
export const search = gql`
export const SEARCH_QUERY = gql`
query Search(
$searchInput: String!
$limit: Int!
$after: String
$excludedObjectNameSingulars: [String!]
$includedObjectNameSingulars: [String!]
$filter: ObjectRecordFilterInput
@ -11,16 +12,26 @@ export const search = gql`
search(
searchInput: $searchInput
limit: $limit
after: $after
excludedObjectNameSingulars: $excludedObjectNameSingulars
includedObjectNameSingulars: $includedObjectNameSingulars
filter: $filter
) {
recordId
objectNameSingular
label
imageUrl
tsRankCD
tsRank
edges {
node {
recordId
objectNameSingular
label
imageUrl
tsRankCD
tsRank
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}
`;

View File

@ -31,69 +31,71 @@ export const useCommandMenuSearchRecords = () => {
const { openRecordInCommandMenu } = useOpenRecordInCommandMenu();
const actionItems = useMemo(() => {
return (searchData?.search ?? []).map((searchRecord, index) => {
const baseAction = {
type: ActionType.Navigation,
scope: ActionScope.Global,
key: searchRecord.recordId,
label: searchRecord.label,
position: index,
Icon: () => (
<Avatar
type={
searchRecord.objectNameSingular === 'company'
? 'squared'
: 'rounded'
}
avatarUrl={searchRecord.imageUrl}
placeholderColorSeed={searchRecord.recordId}
placeholder={searchRecord.label}
/>
),
shouldBeRegistered: () => true,
description: capitalize(searchRecord.objectNameSingular),
shouldCloseCommandMenuOnClick: true,
};
return (searchData?.search.edges.map((edge) => edge.node) ?? []).map(
(searchRecord, index) => {
const baseAction = {
type: ActionType.Navigation,
scope: ActionScope.Global,
key: searchRecord.recordId,
label: searchRecord.label,
position: index,
Icon: () => (
<Avatar
type={
searchRecord.objectNameSingular === 'company'
? 'squared'
: 'rounded'
}
avatarUrl={searchRecord.imageUrl}
placeholderColorSeed={searchRecord.recordId}
placeholder={searchRecord.label}
/>
),
shouldBeRegistered: () => true,
description: capitalize(searchRecord.objectNameSingular),
shouldCloseCommandMenuOnClick: true,
};
if (
[CoreObjectNameSingular.Task, CoreObjectNameSingular.Note].includes(
searchRecord.objectNameSingular as CoreObjectNameSingular,
)
) {
return {
...baseAction,
component: (
<Action
onClick={() => {
searchRecord.objectNameSingular === 'task'
? openRecordInCommandMenu({
recordId: searchRecord.recordId,
objectNameSingular: CoreObjectNameSingular.Task,
})
: openRecordInCommandMenu({
recordId: searchRecord.recordId,
objectNameSingular: CoreObjectNameSingular.Note,
});
}}
preventCommandMenuClosing
/>
),
};
}
if (
[CoreObjectNameSingular.Task, CoreObjectNameSingular.Note].includes(
searchRecord.objectNameSingular as CoreObjectNameSingular,
)
) {
return {
...baseAction,
component: (
<Action
onClick={() => {
searchRecord.objectNameSingular === 'task'
? openRecordInCommandMenu({
recordId: searchRecord.recordId,
objectNameSingular: CoreObjectNameSingular.Task,
})
: openRecordInCommandMenu({
recordId: searchRecord.recordId,
objectNameSingular: CoreObjectNameSingular.Note,
});
<ActionLink
to={AppPath.RecordShowPage}
params={{
objectNameSingular: searchRecord.objectNameSingular,
objectRecordId: searchRecord.recordId,
}}
preventCommandMenuClosing
/>
),
};
}
return {
...baseAction,
component: (
<ActionLink
to={AppPath.RecordShowPage}
params={{
objectNameSingular: searchRecord.objectNameSingular,
objectRecordId: searchRecord.recordId,
}}
/>
),
};
});
},
);
}, [searchData, openRecordInCommandMenu]);
return {