Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 26 additions & 17 deletions js/app/packages/app/component/UnifiedListView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,13 @@ export function UnifiedListView(props: UnifiedListViewProps) {

const emailActive = useEmailLinksStatus();

const validSearchTerms = createMemo(() => {
return debouncedSearchForService().length >= 3;
});
const isSearchActive = createMemo(() => {
return validSearchTerms();
});

const dssQueryParams = createMemo(
(): GetItemsSoupParams => ({
limit: props.defaultDisplayOptions?.limit ?? 100,
Expand Down Expand Up @@ -830,6 +837,7 @@ export function UnifiedListView(props: UnifiedListViewProps) {
email_filters: {
recipients:
emailActive() &&
!isSearchActive() &&
view().viewType !== 'project' &&
(entityTypeFilter().includes('email') ||
entityTypeFilter().length === 0)
Expand Down Expand Up @@ -874,19 +882,6 @@ export function UnifiedListView(props: UnifiedListViewProps) {
})
);

const validSearchTerms = createMemo(() => {
return debouncedSearchForService().length >= 3;
});
const validSearchFilters = createMemo(() => {
const senders = unifiedSearchFilters()?.email?.senders;
if (senders && senders.length > 0) return true;
return false;
});

const isSearchActive = createMemo(() => {
return validSearchTerms() || validSearchFilters();
});

const disableSearchService = createMemo(() => {
return !isSearchActive();
});
Expand Down Expand Up @@ -971,10 +966,13 @@ export function UnifiedListView(props: UnifiedListViewProps) {
const channelsQuery = createChannelsQuery({
disabled: disableChannelsQuery,
});
const dssInfiniteQuery = createDssInfiniteQuery(dssQueryParams, {
disabled: disableDssInfiniteQuery,
requestBody: dssQueryRequestBody,
});
const dssInfiniteQuery = createDssInfiniteQuery(
dssQueryParams,
dssQueryRequestBody,
{
disabled: disableDssInfiniteQuery,
}
);
const searchNameContentInfiniteQuery = createUnifiedSearchInfiniteQuery(
searchUnifiedNameContentQueryParams,
{ disabled: disableSearchService }
Expand All @@ -988,6 +986,16 @@ export function UnifiedListView(props: UnifiedListViewProps) {
};
};

// We want to be to be able to search over locally cached emails without actually
// fetching more data when we have a invalid search term (i.e. one or two chars).
// If we're using search service for a valid term, we can safely fetch more data
// from dss for fuzzy name search since we won't be searching over emails (too big).
const disableFetchMore = createMemo(() => {
const searchAllEmails =
(dssQueryRequestBody().email_filters?.recipients ?? []).length === 0;
return searchText().length > 0 && searchAllEmails;
});

const { UnifiedListComponent, entities, isLoading } =
createUnifiedInfiniteList<
WithNotification<WithSearch<EntityData> | EntityData>
Expand All @@ -1011,6 +1019,7 @@ export function UnifiedListView(props: UnifiedListViewProps) {
entitySort,
searchFilter: nameFuzzySearchFilter,
isSearchActive,
disableFetchMore,
});

createEffect(() => {
Expand Down
8 changes: 4 additions & 4 deletions js/app/packages/core/email-link/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { emailClient } from '@service-email/client';
import { updateUserInfo } from '@service-gql/client';
import { useQuery } from '@tanstack/solid-query';
import { err, okAsync, ResultAsync } from 'neverthrow';
import { createSignal } from 'solid-js';
import { createMemo, createSignal } from 'solid-js';
import { queryClient } from '../../macro-entity/src/queries/client';

export const [emailRefetchInterval, setEmailRefetchInterval] = createSignal<
Expand Down Expand Up @@ -38,12 +38,12 @@ export function useEmailLinksQuery() {

export function useEmailLinksStatus() {
const links = useEmailLinksQuery();
return () => {
return createMemo(() => {
if (!links.data || links.error) {
return false;
}
return links.data?.length > 0;
};
return links.data.length > 0;
});
}

function invalidateEmailLinks() {
Expand Down
2 changes: 1 addition & 1 deletion js/app/packages/macro-entity/src/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export function Provider(props: ParentProps) {
staleTime: 1000 * 10, // 10 seconds
});
queryClient.setQueryDefaults(queryKeys.all.dss, {
staleTime: 1000 * 5, // 5 seconds
staleTime: 1000 * 60, // 1 minute
});
queryClient.setQueryDefaults(queryKeys.all.email, {
staleTime: 1000, // 1 second
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ interface UnifiedInfiniteListContext<T extends EntityData> {
entitySort?: Accessor<EntityComparator<T>>;
searchFilter?: Accessor<EntitiesFilter<T> | undefined>;
isSearchActive?: Accessor<boolean>;
disableFetchMore?: Accessor<boolean>;
}

export function createUnifiedInfiniteList<T extends EntityData>({
Expand All @@ -217,6 +218,7 @@ export function createUnifiedInfiniteList<T extends EntityData>({
entitySort,
searchFilter,
isSearchActive,
disableFetchMore,
}: UnifiedInfiniteListContext<T>) {
const [sortedEntitiesStore, setSortedEntitiesStore] = createStore<T[]>([]);
const allEntities = createMemo(() => {
Expand Down Expand Up @@ -311,7 +313,7 @@ export function createUnifiedInfiniteList<T extends EntityData>({
const searching = isSearchActive?.();

if (searching) {
// NOTE: the default sort will be channels, then local fuzzy name, then serach service
// NOTE: the default sort will be channels, then local fuzzy name, then search service
// avoiding doing an extra sort as a speed optimization
return entities.toSorted(sortEntitiesForSearch);
}
Expand Down Expand Up @@ -388,7 +390,7 @@ export function createUnifiedInfiniteList<T extends EntityData>({

let isFetchingMore = false;
const fetchMoreData = async () => {
if (isFetchingMore) return;
if (disableFetchMore?.() || isFetchingMore) return;

isFetchingMore = true;
const results = entityInfiniteQueries.map((query) => {
Expand Down
23 changes: 13 additions & 10 deletions js/app/packages/macro-entity/src/queries/dss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ const fetchPaginatedDocumentsPost = async ({
apiToken,
params,
requestBody,
signal,
}: {
apiToken?: string;
requestBody?: PostSoupRequest;
params?: PostItemsSoupParams;
signal?: AbortSignal;
}) => {
if (!apiToken) throw new Error('No API token provided');
const Authorization = `Bearer ${apiToken}`;
Expand All @@ -93,6 +95,7 @@ const fetchPaginatedDocumentsPost = async ({
headers: { Authorization, 'Content-Type': 'application/json' },
method: 'POST',
body: requestBody ? JSON.stringify(requestBody) : undefined,
signal,
});
if (!response.ok)
throw new Error('Failed to fetch documents', { cause: response });
Expand All @@ -102,21 +105,20 @@ const fetchPaginatedDocumentsPost = async ({
};

export function createDssInfiniteQuery(
_params?: Accessor<PostItemsSoupParams>,
initialParams?: Accessor<PostItemsSoupParams>,
getRequestBody?: Accessor<PostSoupRequest>,
options?: {
disabled?: Accessor<boolean>;
requestBody?: Accessor<PostSoupRequest>;
}
) {
const params = () => {
const argParams = _params?.();
const argParams = initialParams?.();
let limit = 100;
let sort_method;
let emailView;
const requestBody = options?.requestBody;

if (requestBody) {
const body = requestBody();
if (getRequestBody) {
const body = getRequestBody();
if (body?.limit) {
limit = body.limit;
}
Expand All @@ -140,7 +142,7 @@ export function createDssInfiniteQuery(
const instructionsIdQuery = useInstructionsMdIdQuery();

return useInfiniteQuery(() => {
const requestBody = options?.requestBody?.();
const requestBody = getRequestBody?.();
// Include all filters in query key so query refetches when any filter changes
const documentFilters = requestBody?.document_filters;
const projectFilters = requestBody?.project_filters;
Expand All @@ -166,12 +168,13 @@ export function createDssInfiniteQuery(

return {
queryKey,
queryHash: hashKey(queryKey),
queryFn: ({ pageParam }) => {
queryKeyHashFn: hashKey,
queryFn: ({ pageParam, signal }) => {
return fetchPaginatedDocumentsPost({
apiToken: authQuery.data,
requestBody: requestBody,
requestBody,
params: { cursor: pageParam.cursor },
signal,
});
},
initialPageParam: params(),
Expand Down