favorite folders followup (#8570)
Something changed, which affected the Favorite folder picker checkbox styles -- fixed it! Cleaned up code in `CurrentWorkspaceMemberFavoritesFolders` - removed redundant filtering since favorites are already filtered in `usePrefetchedFavoritesData`. Regarding issue #8569 - I am not sure what to do in this case. Since Folders data is gated by a feature flag, we can't use it in `CurrentWorkspaceMemberFavoritesFolders` to ensure the favorite section renders with empty folders. Currently, the section only appears when at least one favorite exists - may be leave this section open at all times or fix this bug after removal of the feature flag? --------- Co-authored-by: Nitin Koche <nitinkoche@Nitins-MacBook-Pro.local> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -44,7 +44,10 @@ describe('useCreateFavorite', () => {
|
||||
{ wrapper: Wrapper },
|
||||
);
|
||||
|
||||
result.current(favoriteTargetObjectRecord, CoreObjectNameSingular.Person);
|
||||
result.current.createFavorite(
|
||||
favoriteTargetObjectRecord,
|
||||
CoreObjectNameSingular.Person,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mocks[0].result).toHaveBeenCalled();
|
||||
|
||||
@ -38,7 +38,7 @@ describe('useDeleteFavorite', () => {
|
||||
{ wrapper: Wrapper },
|
||||
);
|
||||
|
||||
result.current(favoriteId);
|
||||
result.current.deleteFavorite(favoriteId);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mocks[1].result).toHaveBeenCalled();
|
||||
|
||||
@ -38,6 +38,6 @@ describe('useFavorites', () => {
|
||||
{ wrapper: Wrapper },
|
||||
);
|
||||
|
||||
expect(result.current).toEqual(sortedFavorites);
|
||||
expect(result.current.sortedFavorites).toEqual(sortedFavorites);
|
||||
});
|
||||
});
|
||||
|
||||
@ -54,7 +54,10 @@ describe('useReorderFavorite', () => {
|
||||
announce: () => {},
|
||||
};
|
||||
|
||||
result.current(dragAndDropResult, responderProvided);
|
||||
result.current.handleReorderFavorite(
|
||||
dragAndDropResult,
|
||||
responderProvided,
|
||||
);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
|
||||
@ -34,5 +34,5 @@ export const useCreateFavorite = () => {
|
||||
});
|
||||
};
|
||||
|
||||
return createFavorite;
|
||||
return { createFavorite };
|
||||
};
|
||||
|
||||
@ -28,5 +28,5 @@ export const useCreateFavoriteFolder = () => {
|
||||
});
|
||||
};
|
||||
|
||||
return createNewFavoriteFolder;
|
||||
return { createNewFavoriteFolder };
|
||||
};
|
||||
|
||||
@ -10,5 +10,5 @@ export const useDeleteFavorite = () => {
|
||||
deleteOneRecord(favoriteId);
|
||||
};
|
||||
|
||||
return deleteFavorite;
|
||||
return { deleteFavorite };
|
||||
};
|
||||
|
||||
@ -1,23 +1,46 @@
|
||||
import { Favorite } from '@/favorites/types/Favorite';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useReadFindManyRecordsQueryInCache } from '@/object-record/cache/hooks/useReadFindManyRecordsQueryInCache';
|
||||
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData';
|
||||
import { PREFETCH_CONFIG } from '@/prefetch/constants/PrefetchConfig';
|
||||
import { usePrefetchRunQuery } from '@/prefetch/hooks/internal/usePrefetchRunQuery';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
|
||||
export const useDeleteFavoriteFolder = () => {
|
||||
const { deleteOneRecord } = useDeleteOneRecord({
|
||||
objectNameSingular: CoreObjectNameSingular.FavoriteFolder,
|
||||
});
|
||||
const { upsertFavorites, favorites, workspaceFavorites } =
|
||||
usePrefetchedFavoritesData();
|
||||
|
||||
const { upsertRecordsInCache } = usePrefetchRunQuery<Favorite>({
|
||||
prefetchKey: PrefetchKey.AllFavorites,
|
||||
});
|
||||
|
||||
const { objectMetadataItem } = useObjectMetadataItem({
|
||||
objectNameSingular:
|
||||
PREFETCH_CONFIG[PrefetchKey.AllFavorites].objectNameSingular,
|
||||
});
|
||||
|
||||
const { readFindManyRecordsQueryInCache } =
|
||||
useReadFindManyRecordsQueryInCache({
|
||||
objectMetadataItem,
|
||||
});
|
||||
|
||||
const deleteFavoriteFolder = async (folderId: string): Promise<void> => {
|
||||
await deleteOneRecord(folderId);
|
||||
|
||||
const updatedFavorites = [
|
||||
...favorites.filter((favorite) => favorite.favoriteFolderId !== folderId),
|
||||
...workspaceFavorites,
|
||||
];
|
||||
const allFavorites = readFindManyRecordsQueryInCache<Favorite>({
|
||||
queryVariables: {},
|
||||
recordGqlFields: PREFETCH_CONFIG[
|
||||
PrefetchKey.AllFavorites
|
||||
].operationSignatureFactory({ objectMetadataItem }).fields,
|
||||
});
|
||||
|
||||
upsertFavorites(updatedFavorites);
|
||||
const updatedFavorites = allFavorites.filter(
|
||||
(favorite) => favorite.favoriteFolderId !== folderId,
|
||||
);
|
||||
|
||||
upsertRecordsInCache(updatedFavorites);
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
@ -52,5 +52,5 @@ export const useFavorites = () => {
|
||||
],
|
||||
);
|
||||
|
||||
return sortedFavorites;
|
||||
return { sortedFavorites };
|
||||
};
|
||||
|
||||
@ -1,62 +1,30 @@
|
||||
import { sortFavorites } from '@/favorites/utils/sortFavorites';
|
||||
import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { View } from '@/views/types/View';
|
||||
import { useMemo } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { useFavoritesMetadata } from './useFavoritesMetadata';
|
||||
import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData';
|
||||
import { usePrefetchedFavoritesFoldersData } from './usePrefetchedFavoritesFoldersData';
|
||||
|
||||
export const useFavoritesByFolder = () => {
|
||||
const { favorites } = usePrefetchedFavoritesData();
|
||||
const { favoriteFolders } = usePrefetchedFavoritesFoldersData();
|
||||
const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews);
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
const getObjectRecordIdentifierByNameSingular =
|
||||
useGetObjectRecordIdentifierByNameSingular();
|
||||
|
||||
const { objectMetadataItem: favoriteObjectMetadataItem } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.Favorite,
|
||||
});
|
||||
|
||||
const favoriteRelationFields = useMemo(
|
||||
() =>
|
||||
favoriteObjectMetadataItem.fields.filter(
|
||||
(fieldMetadataItem) =>
|
||||
fieldMetadataItem.type === FieldMetadataType.Relation &&
|
||||
fieldMetadataItem.name !== 'workspaceMember' &&
|
||||
fieldMetadataItem.name !== 'favoriteFolder',
|
||||
),
|
||||
[favoriteObjectMetadataItem.fields],
|
||||
);
|
||||
|
||||
const favoritesByFolder = useMemo(() => {
|
||||
return favoriteFolders.map((folder) => ({
|
||||
folderId: folder.id,
|
||||
folderName: folder.name,
|
||||
favorites: sortFavorites(
|
||||
favorites.filter((favorite) => favorite.favoriteFolderId === folder.id),
|
||||
favoriteRelationFields,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
true,
|
||||
views,
|
||||
objectMetadataItems,
|
||||
),
|
||||
}));
|
||||
}, [
|
||||
favoriteFolders,
|
||||
favorites,
|
||||
favoriteRelationFields,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
const {
|
||||
views,
|
||||
objectMetadataItems,
|
||||
]);
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
favoriteRelationFields,
|
||||
} = useFavoritesMetadata();
|
||||
|
||||
return favoritesByFolder;
|
||||
const favoritesByFolder = favoriteFolders.map((folder) => ({
|
||||
folderId: folder.id,
|
||||
folderName: folder.name,
|
||||
favorites: sortFavorites(
|
||||
favorites.filter((favorite) => favorite.favoriteFolderId === folder.id),
|
||||
favoriteRelationFields,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
true,
|
||||
views,
|
||||
objectMetadataItems,
|
||||
),
|
||||
}));
|
||||
|
||||
return { favoritesByFolder };
|
||||
};
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { View } from '@/views/types/View';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
|
||||
export const useFavoritesMetadata = () => {
|
||||
const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews);
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
const getObjectRecordIdentifierByNameSingular =
|
||||
useGetObjectRecordIdentifierByNameSingular();
|
||||
|
||||
const { objectMetadataItem: favoriteObjectMetadataItem } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.Favorite,
|
||||
});
|
||||
|
||||
const favoriteRelationFields = favoriteObjectMetadataItem.fields.filter(
|
||||
(fieldMetadataItem) =>
|
||||
fieldMetadataItem.type === FieldMetadataType.Relation &&
|
||||
fieldMetadataItem.name !== 'workspaceMember' &&
|
||||
fieldMetadataItem.name !== 'favoriteFolder',
|
||||
);
|
||||
|
||||
return {
|
||||
views,
|
||||
objectMetadataItems,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
favoriteRelationFields,
|
||||
};
|
||||
};
|
||||
@ -12,7 +12,7 @@ export const useReorderFavorite = () => {
|
||||
objectNameSingular: CoreObjectNameSingular.Favorite,
|
||||
});
|
||||
|
||||
const reorderFavorite: OnDragEndResponder = (result) => {
|
||||
const handleReorderFavorite: OnDragEndResponder = (result) => {
|
||||
if (!result.destination) return;
|
||||
|
||||
const draggedFavoriteId = result.draggableId;
|
||||
@ -37,5 +37,5 @@ export const useReorderFavorite = () => {
|
||||
});
|
||||
};
|
||||
|
||||
return reorderFavorite;
|
||||
return { handleReorderFavorite };
|
||||
};
|
||||
|
||||
@ -1,50 +1,28 @@
|
||||
import { sortFavorites } from '@/favorites/utils/sortFavorites';
|
||||
import { useGetObjectRecordIdentifierByNameSingular } from '@/object-metadata/hooks/useGetObjectRecordIdentifierByNameSingular';
|
||||
import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem';
|
||||
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { usePrefetchedData } from '@/prefetch/hooks/usePrefetchedData';
|
||||
import { PrefetchKey } from '@/prefetch/types/PrefetchKey';
|
||||
import { View } from '@/views/types/View';
|
||||
import { useMemo } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { FieldMetadataType } from '~/generated-metadata/graphql';
|
||||
import { useFavoritesMetadata } from './useFavoritesMetadata';
|
||||
import { usePrefetchedFavoritesData } from './usePrefetchedFavoritesData';
|
||||
|
||||
export const useSortedFavorites = () => {
|
||||
const { favorites, workspaceFavorites } = usePrefetchedFavoritesData();
|
||||
const { records: views } = usePrefetchedData<View>(PrefetchKey.AllViews);
|
||||
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
|
||||
const { objectMetadataItem: favoriteObjectMetadataItem } =
|
||||
useObjectMetadataItem({
|
||||
objectNameSingular: CoreObjectNameSingular.Favorite,
|
||||
});
|
||||
|
||||
const getObjectRecordIdentifierByNameSingular =
|
||||
useGetObjectRecordIdentifierByNameSingular();
|
||||
|
||||
const favoriteRelationFieldMetadataItems = useMemo(
|
||||
() =>
|
||||
favoriteObjectMetadataItem.fields.filter(
|
||||
(fieldMetadataItem) =>
|
||||
fieldMetadataItem.type === FieldMetadataType.Relation &&
|
||||
fieldMetadataItem.name !== 'workspaceMember' &&
|
||||
fieldMetadataItem.name !== 'favoriteFolder',
|
||||
),
|
||||
[favoriteObjectMetadataItem.fields],
|
||||
);
|
||||
const {
|
||||
views,
|
||||
objectMetadataItems,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
favoriteRelationFields,
|
||||
} = useFavoritesMetadata();
|
||||
|
||||
const favoritesSorted = useMemo(() => {
|
||||
return sortFavorites(
|
||||
favorites,
|
||||
favoriteRelationFieldMetadataItems,
|
||||
favoriteRelationFields,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
true,
|
||||
views,
|
||||
objectMetadataItems,
|
||||
);
|
||||
}, [
|
||||
favoriteRelationFieldMetadataItems,
|
||||
favoriteRelationFields,
|
||||
favorites,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
views,
|
||||
@ -54,14 +32,14 @@ export const useSortedFavorites = () => {
|
||||
const workspaceFavoritesSorted = useMemo(() => {
|
||||
return sortFavorites(
|
||||
workspaceFavorites.filter((favorite) => favorite.viewId),
|
||||
favoriteRelationFieldMetadataItems,
|
||||
favoriteRelationFields,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
false,
|
||||
views,
|
||||
objectMetadataItems,
|
||||
);
|
||||
}, [
|
||||
favoriteRelationFieldMetadataItems,
|
||||
favoriteRelationFields,
|
||||
getObjectRecordIdentifierByNameSingular,
|
||||
workspaceFavorites,
|
||||
views,
|
||||
|
||||
@ -52,5 +52,5 @@ export const useWorkspaceFavorites = () => {
|
||||
],
|
||||
);
|
||||
|
||||
return sortedWorkspaceFavorites;
|
||||
return { sortedWorkspaceFavorites };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user