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:
@ -61,9 +61,9 @@ export const CurrentWorkspaceMemberFavorites = ({
|
||||
const selectedFavoriteIndex = folder.favorites.findIndex((favorite) =>
|
||||
isLocationMatchingFavorite(currentPath, currentViewPath, favorite),
|
||||
);
|
||||
const handleReorderFavorite = useReorderFavorite();
|
||||
const { handleReorderFavorite } = useReorderFavorite();
|
||||
|
||||
const deleteFavorite = useDeleteFavorite();
|
||||
const { deleteFavorite } = useDeleteFavorite();
|
||||
|
||||
const favoriteFolderContentLength = folder.favorites.length;
|
||||
|
||||
@ -154,6 +154,7 @@ export const CurrentWorkspaceMemberFavorites = ({
|
||||
key={favorite.id}
|
||||
draggableId={favorite.id}
|
||||
index={index}
|
||||
isInsideScrollableContainer
|
||||
itemComponent={
|
||||
<NavigationDrawerSubItem
|
||||
key={favorite.id}
|
||||
|
||||
@ -4,8 +4,8 @@ import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
import {
|
||||
IconFolderPlus,
|
||||
IconHeartOff,
|
||||
isDefined,
|
||||
LightIconButton,
|
||||
isDefined,
|
||||
} from 'twenty-ui';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
@ -32,9 +32,9 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => {
|
||||
const currentViewPath = useLocation().pathname + useLocation().search;
|
||||
const theme = useTheme();
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
const favorites = useFavorites();
|
||||
const deleteFavorite = useDeleteFavorite();
|
||||
const handleReorderFavorite = useReorderFavorite();
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
const { deleteFavorite } = useDeleteFavorite();
|
||||
const { handleReorderFavorite } = useReorderFavorite();
|
||||
const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] =
|
||||
useRecoilState(isFavoriteFolderCreatingState);
|
||||
|
||||
@ -50,24 +50,25 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => {
|
||||
const toggleNewFolder = () => {
|
||||
setIsFavoriteFolderCreating((current) => !current);
|
||||
};
|
||||
const shouldDisplayFavoritesWithFeatureFlagEnabled = true;
|
||||
|
||||
//todo: remove this logic once feature flag gating is removed
|
||||
const shouldDisplayFavoritesWithoutFeatureFlagEnabled =
|
||||
favorites.length > 0 || isFavoriteFolderCreating;
|
||||
|
||||
const shouldDisplayFavorites = isFavoriteFolderEnabled
|
||||
? shouldDisplayFavoritesWithFeatureFlagEnabled
|
||||
: shouldDisplayFavoritesWithoutFeatureFlagEnabled;
|
||||
|
||||
if (loading && isDefined(currentWorkspaceMember)) {
|
||||
return <FavoritesSkeletonLoader />;
|
||||
}
|
||||
|
||||
const currentWorkspaceMemberFavorites = favorites.filter(
|
||||
(favorite) => favorite.workspaceMemberId === currentWorkspaceMember?.id,
|
||||
);
|
||||
|
||||
const orphanFavorites = currentWorkspaceMemberFavorites.filter(
|
||||
const orphanFavorites = favorites.filter(
|
||||
(favorite) => !favorite.favoriteFolderId,
|
||||
);
|
||||
|
||||
if (
|
||||
(!currentWorkspaceMemberFavorites ||
|
||||
currentWorkspaceMemberFavorites.length === 0) &&
|
||||
!isFavoriteFolderCreating
|
||||
) {
|
||||
if (!shouldDisplayFavorites) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -104,6 +105,7 @@ export const CurrentWorkspaceMemberFavoritesFolders = () => {
|
||||
key={favorite.id}
|
||||
draggableId={favorite.id}
|
||||
index={index}
|
||||
isInsideScrollableContainer={true}
|
||||
itemComponent={
|
||||
<NavigationDrawerItem
|
||||
key={favorite.id}
|
||||
|
||||
@ -38,6 +38,7 @@ export const FavoriteFolderNavigationDrawerItemDropdown = ({
|
||||
dropdownHotkeyScope={{
|
||||
scope: FavoriteFolderHotkeyScope.FavoriteFolderRightIconDropdown,
|
||||
}}
|
||||
usePortal
|
||||
data-select-disable
|
||||
clickableComponent={
|
||||
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
|
||||
|
||||
@ -18,8 +18,8 @@ export const FavoriteFolders = ({
|
||||
}: FavoriteFoldersProps) => {
|
||||
const [newFolderName, setNewFolderName] = useState('');
|
||||
|
||||
const favoritesByFolder = useFavoritesByFolder();
|
||||
const createFavoriteFolder = useCreateFavoriteFolder();
|
||||
const { favoritesByFolder } = useFavoritesByFolder();
|
||||
const { createNewFavoriteFolder } = useCreateFavoriteFolder();
|
||||
|
||||
const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] =
|
||||
useRecoilState(isFavoriteFolderCreatingState);
|
||||
@ -33,12 +33,12 @@ export const FavoriteFolders = ({
|
||||
|
||||
setIsFavoriteFolderCreating(false);
|
||||
setNewFolderName('');
|
||||
await createFavoriteFolder(value);
|
||||
await createNewFavoriteFolder(value);
|
||||
return true;
|
||||
};
|
||||
|
||||
const handleClickOutside = async (
|
||||
event: MouseEvent | TouchEvent,
|
||||
_event: MouseEvent | TouchEvent,
|
||||
value: string,
|
||||
) => {
|
||||
if (!value) {
|
||||
@ -48,7 +48,7 @@ export const FavoriteFolders = ({
|
||||
|
||||
setIsFavoriteFolderCreating(false);
|
||||
setNewFolderName('');
|
||||
await createFavoriteFolder(value);
|
||||
await createNewFavoriteFolder(value);
|
||||
};
|
||||
|
||||
const handleCancelFavoriteFolderCreation = () => {
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import { IconButton, IconHeart } from 'twenty-ui';
|
||||
|
||||
type PageFavoriteButtonProps = {
|
||||
isFavorite: boolean;
|
||||
onClick?: () => void;
|
||||
};
|
||||
|
||||
export const PageFavoriteButton = ({
|
||||
isFavorite,
|
||||
onClick,
|
||||
}: PageFavoriteButtonProps) => (
|
||||
<IconButton
|
||||
Icon={IconHeart}
|
||||
size="medium"
|
||||
variant="secondary"
|
||||
data-testid="add-button"
|
||||
accent={isFavorite ? 'danger' : 'default'}
|
||||
onClick={onClick}
|
||||
/>
|
||||
);
|
||||
@ -0,0 +1,51 @@
|
||||
import { PageFavoriteButton } from '@/favorites/components/PageFavoriteButton';
|
||||
import { FavoriteFolderPicker } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPicker';
|
||||
import { FavoriteFolderPickerEffect } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPickerEffect';
|
||||
import { FavoriteFolderPickerComponentInstanceContext } from '@/favorites/favorite-folder-picker/scopes/FavoriteFolderPickerScope';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
|
||||
|
||||
type PageFavoriteFoldersDropdownProps = {
|
||||
dropdownId: string;
|
||||
isFavorite: boolean;
|
||||
record?: ObjectRecord;
|
||||
objectNameSingular: string;
|
||||
};
|
||||
|
||||
export const PageFavoriteFoldersDropdown = ({
|
||||
dropdownId,
|
||||
isFavorite,
|
||||
record,
|
||||
objectNameSingular,
|
||||
}: PageFavoriteFoldersDropdownProps) => {
|
||||
const { closeDropdown } = useDropdown(dropdownId);
|
||||
|
||||
return (
|
||||
<FavoriteFolderPickerComponentInstanceContext
|
||||
favoriteFoldersScopeId={dropdownId}
|
||||
>
|
||||
<DropdownScope dropdownScopeId={dropdownId}>
|
||||
<Dropdown
|
||||
dropdownId={dropdownId}
|
||||
dropdownPlacement="bottom-start"
|
||||
clickableComponent={<PageFavoriteButton isFavorite={isFavorite} />}
|
||||
dropdownComponents={
|
||||
<>
|
||||
<FavoriteFolderPickerEffect record={record} />
|
||||
<FavoriteFolderPicker
|
||||
onSubmit={closeDropdown}
|
||||
record={record}
|
||||
objectNameSingular={objectNameSingular}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
dropdownHotkeyScope={{
|
||||
scope: dropdownId,
|
||||
}}
|
||||
/>
|
||||
</DropdownScope>
|
||||
</FavoriteFolderPickerComponentInstanceContext>
|
||||
);
|
||||
};
|
||||
@ -1,10 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { MenuItemMultiSelect } from '@ui/navigation/menu-item/components/MenuItemMultiSelect';
|
||||
|
||||
const StyledNoGapMenuItem = styled(MenuItemMultiSelect)`
|
||||
& > div {
|
||||
gap: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
export const FavoriteFolderMenuItemMultiSelect = StyledNoGapMenuItem;
|
||||
@ -36,7 +36,7 @@ export const FavoriteFolderPicker = ({
|
||||
FavoriteFolderPickerInstanceContext,
|
||||
);
|
||||
|
||||
const { getFoldersByIds, toggleFolderSelection } = useFavoriteFolderPicker({
|
||||
const { favoriteFolders, toggleFolderSelection } = useFavoriteFolderPicker({
|
||||
record,
|
||||
objectNameSingular,
|
||||
});
|
||||
@ -45,8 +45,7 @@ export const FavoriteFolderPicker = ({
|
||||
favoriteFolderSearchFilterComponentState,
|
||||
);
|
||||
|
||||
const folders = getFoldersByIds();
|
||||
const filteredFolders = folders.filter((folder) =>
|
||||
const filteredFolders = favoriteFolders.filter((folder) =>
|
||||
folder.name
|
||||
.toLowerCase()
|
||||
.includes(favoriteFoldersSearchFilter.toLowerCase()),
|
||||
@ -94,7 +93,7 @@ export const FavoriteFolderPicker = ({
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
<FavoriteFolderPickerList
|
||||
folders={folders}
|
||||
folders={favoriteFolders}
|
||||
toggleFolderSelection={toggleFolderSelection}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
|
||||
@ -30,7 +30,7 @@ export const FavoriteFolderPickerEffect = ({
|
||||
|
||||
const { favoriteFolders } = usePrefetchedFavoritesFoldersData();
|
||||
|
||||
const favorites = useFavorites();
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
const setCheckedState = useSetRecoilComponentStateV2(
|
||||
favoriteFolderPickerCheckedComponentState,
|
||||
);
|
||||
|
||||
@ -14,10 +14,6 @@ const StyledFooter = styled.div`
|
||||
border-top: 1px solid ${({ theme }) => theme.border.color.light};
|
||||
`;
|
||||
|
||||
const StyledIconPlus = styled(IconPlus)`
|
||||
padding-left: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
export const FavoriteFolderPickerFooter = () => {
|
||||
const [, setIsFavoriteFolderCreating] = useRecoilState(
|
||||
isFavoriteFolderCreatingState,
|
||||
@ -35,7 +31,7 @@ export const FavoriteFolderPickerFooter = () => {
|
||||
closeDropdown();
|
||||
}}
|
||||
text="Add folder"
|
||||
LeftIcon={() => <StyledIconPlus size={theme.icon.size.md} />}
|
||||
LeftIcon={() => <IconPlus size={theme.icon.size.md} />}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</StyledFooter>
|
||||
|
||||
@ -4,8 +4,7 @@ import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
import styled from '@emotion/styled';
|
||||
import { MenuItem } from 'twenty-ui';
|
||||
import { FavoriteFolderMenuItemMultiSelect } from './FavoriteFolderMenuItemMultiSelect';
|
||||
import { MenuItem, MenuItemMultiSelect } from 'twenty-ui';
|
||||
|
||||
const StyledItemsContainer = styled.div`
|
||||
width: 100%;
|
||||
@ -30,6 +29,7 @@ export const FavoriteFolderPickerList = ({
|
||||
const [favoriteFoldersSearchFilter] = useRecoilComponentStateV2(
|
||||
favoriteFolderSearchFilterComponentState,
|
||||
);
|
||||
|
||||
const [favoriteFolderPickerChecked] = useRecoilComponentStateV2(
|
||||
favoriteFolderPickerCheckedComponentState,
|
||||
);
|
||||
@ -47,7 +47,7 @@ export const FavoriteFolderPickerList = ({
|
||||
return (
|
||||
<StyledItemsContainer>
|
||||
{showNoFolderOption && (
|
||||
<FavoriteFolderMenuItemMultiSelect
|
||||
<MenuItemMultiSelect
|
||||
key={`menu-${NO_FOLDER_ID}`}
|
||||
onSelectChange={() => toggleFolderSelection(NO_FOLDER_ID)}
|
||||
selected={favoriteFolderPickerChecked.includes(NO_FOLDER_ID)}
|
||||
@ -60,7 +60,7 @@ export const FavoriteFolderPickerList = ({
|
||||
)}
|
||||
{filteredFolders.length > 0
|
||||
? filteredFolders.map((folder) => (
|
||||
<FavoriteFolderMenuItemMultiSelect
|
||||
<MenuItemMultiSelect
|
||||
key={`menu-${folder.id}`}
|
||||
onSelectChange={() => toggleFolderSelection(folder.id)}
|
||||
selected={favoriteFolderPickerChecked.includes(folder.id)}
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
import { favoriteFolderIdsPickerComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderIdPickerComponentState';
|
||||
import { favoriteFolderPickerCheckedComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerCheckedComponentState';
|
||||
import { favoriteFolderPickerComponentFamilyState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerComponentFamilyState';
|
||||
import { favoriteFoldersComponentSelector } from '@/favorites/favorite-folder-picker/states/selectors/favoriteFoldersComponentSelector';
|
||||
import { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite';
|
||||
import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite';
|
||||
import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
@ -8,7 +7,7 @@ import { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
@ -17,46 +16,26 @@ type useFavoriteFolderPickerProps = {
|
||||
objectNameSingular: string;
|
||||
};
|
||||
|
||||
type FolderOperations = {
|
||||
getFoldersByIds: () => FavoriteFolder[];
|
||||
type useFavoriteFolderPickerReturnType = {
|
||||
favoriteFolders: FavoriteFolder[];
|
||||
toggleFolderSelection: (folderId: string) => Promise<void>;
|
||||
};
|
||||
|
||||
export const useFavoriteFolderPicker = ({
|
||||
record,
|
||||
objectNameSingular,
|
||||
}: useFavoriteFolderPickerProps): FolderOperations => {
|
||||
const [favoriteFolderIdsPicker] = useRecoilComponentStateV2(
|
||||
favoriteFolderIdsPickerComponentState,
|
||||
);
|
||||
|
||||
}: useFavoriteFolderPickerProps): useFavoriteFolderPickerReturnType => {
|
||||
const favoriteFoldersMultiSelectCheckedState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
favoriteFolderPickerCheckedComponentState,
|
||||
);
|
||||
|
||||
const favoriteFolderPickerFamilyState = useRecoilComponentCallbackStateV2(
|
||||
favoriteFolderPickerComponentFamilyState,
|
||||
);
|
||||
const { sortedFavorites: favorites } = useFavorites();
|
||||
const { createFavorite } = useCreateFavorite();
|
||||
const { deleteFavorite } = useDeleteFavorite();
|
||||
|
||||
const favorites = useFavorites();
|
||||
const createFavorite = useCreateFavorite();
|
||||
const deleteFavorite = useDeleteFavorite();
|
||||
|
||||
const getFoldersByIds = useRecoilCallback(
|
||||
({ snapshot }) =>
|
||||
(): FavoriteFolder[] => {
|
||||
return favoriteFolderIdsPicker
|
||||
.map((folderId) => {
|
||||
const folderValue = snapshot
|
||||
.getLoadable(favoriteFolderPickerFamilyState(folderId))
|
||||
.getValue();
|
||||
|
||||
return folderValue;
|
||||
})
|
||||
.filter((folder): folder is FavoriteFolder => isDefined(folder));
|
||||
},
|
||||
[favoriteFolderIdsPicker, favoriteFolderPickerFamilyState],
|
||||
const favoriteFolders = useRecoilComponentValueV2(
|
||||
favoriteFoldersComponentSelector,
|
||||
);
|
||||
|
||||
const toggleFolderSelection = useRecoilCallback(
|
||||
@ -123,7 +102,7 @@ export const useFavoriteFolderPicker = ({
|
||||
);
|
||||
|
||||
return {
|
||||
getFoldersByIds,
|
||||
favoriteFolders,
|
||||
toggleFolderSelection,
|
||||
};
|
||||
};
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
type FavoriteFolderPickerScopeProps = {
|
||||
type FavoriteFolderPickerComponentInstanceContextProps = {
|
||||
children: ReactNode;
|
||||
favoriteFoldersScopeId: string;
|
||||
};
|
||||
|
||||
export const FavoriteFolderPickerScope = ({
|
||||
export const FavoriteFolderPickerComponentInstanceContext = ({
|
||||
children,
|
||||
favoriteFoldersScopeId,
|
||||
}: FavoriteFolderPickerScopeProps) => {
|
||||
}: FavoriteFolderPickerComponentInstanceContextProps) => {
|
||||
return (
|
||||
<FavoriteFolderPickerInstanceContext.Provider
|
||||
value={{ instanceId: favoriteFoldersScopeId }}
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const favoriteFolderLoadingComponentState =
|
||||
createComponentStateV2<boolean>({
|
||||
key: 'favoriteFoldersLoadingComponentState',
|
||||
defaultValue: false,
|
||||
componentInstanceContext: FavoriteFolderPickerInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,31 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { favoriteFolderIdsPickerComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderIdPickerComponentState';
|
||||
import { favoriteFolderPickerComponentFamilyState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerComponentFamilyState';
|
||||
import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
||||
import { createComponentSelectorV2 } from '@/ui/utilities/state/component-state/utils/createComponentSelectorV2';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
export const favoriteFoldersComponentSelector = createComponentSelectorV2<
|
||||
FavoriteFolder[]
|
||||
>({
|
||||
key: 'favoriteFoldersComponentSelector',
|
||||
componentInstanceContext: FavoriteFolderPickerInstanceContext,
|
||||
get:
|
||||
({ instanceId }) =>
|
||||
({ get }) => {
|
||||
const folderIds = get(
|
||||
favoriteFolderIdsPickerComponentState.atomFamily({ instanceId }),
|
||||
);
|
||||
|
||||
return folderIds
|
||||
.map((folderId: string) =>
|
||||
get(
|
||||
favoriteFolderPickerComponentFamilyState.atomFamily({
|
||||
instanceId,
|
||||
familyKey: folderId,
|
||||
}),
|
||||
),
|
||||
)
|
||||
.filter((folder): folder is FavoriteFolder => isDefined(folder));
|
||||
},
|
||||
});
|
||||
@ -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