Favorite folders (#7998)
closes - #5755 --------- Co-authored-by: martmull <martmull@hotmail.fr> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -0,0 +1,10 @@
|
||||
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;
|
||||
@ -0,0 +1,104 @@
|
||||
import { FavoriteFolderPickerFooter } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPickerFooter';
|
||||
import { FavoriteFolderPickerList } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPickerList';
|
||||
import { FavoriteFolderPickerSearchInput } from '@/favorites/favorite-folder-picker/components/FavoriteFolderPickerSearchInput';
|
||||
import { useFavoriteFolderPicker } from '@/favorites/favorite-folder-picker/hooks/useFavoriteFolderPicker';
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { favoriteFolderSearchFilterComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFoldersSearchFilterComponentState';
|
||||
import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState';
|
||||
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
|
||||
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownMenuSeparator } from '@/ui/layout/dropdown/components/DropdownMenuSeparator';
|
||||
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
|
||||
type FavoriteFolderPickerProps = {
|
||||
onSubmit?: () => void;
|
||||
record?: ObjectRecord;
|
||||
objectNameSingular: string;
|
||||
};
|
||||
|
||||
const NO_FOLDER_ID = 'no-folder';
|
||||
|
||||
export const FavoriteFolderPicker = ({
|
||||
onSubmit,
|
||||
record,
|
||||
objectNameSingular,
|
||||
}: FavoriteFolderPickerProps) => {
|
||||
const [isFavoriteFolderCreating, setIsFavoriteFolderCreating] =
|
||||
useRecoilState(isFavoriteFolderCreatingState);
|
||||
|
||||
const instanceId = useAvailableComponentInstanceIdOrThrow(
|
||||
FavoriteFolderPickerInstanceContext,
|
||||
);
|
||||
|
||||
const { getFoldersByIds, toggleFolderSelection } = useFavoriteFolderPicker({
|
||||
record,
|
||||
objectNameSingular,
|
||||
});
|
||||
|
||||
const [favoriteFoldersSearchFilter] = useRecoilComponentStateV2(
|
||||
favoriteFolderSearchFilterComponentState,
|
||||
);
|
||||
|
||||
const folders = getFoldersByIds();
|
||||
const filteredFolders = folders.filter((folder) =>
|
||||
folder.name
|
||||
.toLowerCase()
|
||||
.includes(favoriteFoldersSearchFilter.toLowerCase()),
|
||||
);
|
||||
|
||||
const showNoFolderOption =
|
||||
!favoriteFoldersSearchFilter ||
|
||||
'no folder'.includes(favoriteFoldersSearchFilter.toLowerCase());
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.Escape,
|
||||
() => {
|
||||
if (isFavoriteFolderCreating) {
|
||||
setIsFavoriteFolderCreating(false);
|
||||
return;
|
||||
}
|
||||
onSubmit?.();
|
||||
},
|
||||
instanceId,
|
||||
[onSubmit, isFavoriteFolderCreating],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
Key.Enter,
|
||||
() => {
|
||||
if (filteredFolders.length === 1 && !showNoFolderOption) {
|
||||
toggleFolderSelection(filteredFolders[0].id);
|
||||
onSubmit?.();
|
||||
return;
|
||||
}
|
||||
|
||||
if (showNoFolderOption && filteredFolders.length === 0) {
|
||||
toggleFolderSelection(NO_FOLDER_ID);
|
||||
onSubmit?.();
|
||||
return;
|
||||
}
|
||||
},
|
||||
instanceId,
|
||||
[filteredFolders, showNoFolderOption, toggleFolderSelection, onSubmit],
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownMenu data-select-disable>
|
||||
<FavoriteFolderPickerSearchInput />
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItemsContainer hasMaxHeight>
|
||||
<FavoriteFolderPickerList
|
||||
folders={folders}
|
||||
toggleFolderSelection={toggleFolderSelection}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
<FavoriteFolderPickerFooter />
|
||||
</DropdownMenu>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,82 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
import { isDeeplyEqual } from '~/utils/isDeeplyEqual';
|
||||
|
||||
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 { useFavorites } from '@/favorites/hooks/useFavorites';
|
||||
import { usePrefetchedFavoritesFoldersData } from '@/favorites/hooks/usePrefetchedFavoritesFoldersData';
|
||||
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 { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
|
||||
|
||||
type FavoriteFolderPickerEffectProps = {
|
||||
record?: ObjectRecord;
|
||||
};
|
||||
|
||||
export const FavoriteFolderPickerEffect = ({
|
||||
record,
|
||||
}: FavoriteFolderPickerEffectProps) => {
|
||||
const [favoriteFolderIdsPicker, setFavoriteFolderIdsPicker] =
|
||||
useRecoilComponentStateV2(favoriteFolderIdsPickerComponentState);
|
||||
|
||||
const favoriteFolderPickerFamilyState = useRecoilComponentCallbackStateV2(
|
||||
favoriteFolderPickerComponentFamilyState,
|
||||
);
|
||||
|
||||
const { favoriteFolders } = usePrefetchedFavoritesFoldersData();
|
||||
|
||||
const favorites = useFavorites();
|
||||
const setCheckedState = useSetRecoilComponentStateV2(
|
||||
favoriteFolderPickerCheckedComponentState,
|
||||
);
|
||||
|
||||
const updateFolders = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
(folders: FavoriteFolder[]) => {
|
||||
folders.forEach((folder) => {
|
||||
const currentFolder = snapshot
|
||||
.getLoadable(favoriteFolderPickerFamilyState(folder.id))
|
||||
.getValue();
|
||||
|
||||
if (!isDeeplyEqual(folder, currentFolder)) {
|
||||
set(favoriteFolderPickerFamilyState(folder.id), folder);
|
||||
}
|
||||
});
|
||||
},
|
||||
[favoriteFolderPickerFamilyState],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDefined(favoriteFolders)) {
|
||||
updateFolders(favoriteFolders);
|
||||
|
||||
const folderIds = favoriteFolders.map((folder) => folder.id);
|
||||
if (!isDeeplyEqual(folderIds, favoriteFolderIdsPicker)) {
|
||||
setFavoriteFolderIdsPicker(folderIds);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
favoriteFolders,
|
||||
favoriteFolderIdsPicker,
|
||||
setFavoriteFolderIdsPicker,
|
||||
updateFolders,
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
const targetId = record?.id;
|
||||
const checkedFolderIds = favorites
|
||||
.filter(
|
||||
(favorite) =>
|
||||
favorite.recordId === targetId && favorite.workspaceMemberId,
|
||||
)
|
||||
.map((favorite) => favorite.favoriteFolderId || 'no-folder');
|
||||
setCheckedState(checkedFolderIds);
|
||||
}, [favorites, setCheckedState, record?.id]);
|
||||
|
||||
return null;
|
||||
};
|
||||
@ -0,0 +1,43 @@
|
||||
import { FAVORITE_FOLDER_PICKER_DROPDOWN_ID } from '@/favorites/favorite-folder-picker/constants/FavoriteFolderPickerDropdownId';
|
||||
import { isFavoriteFolderCreatingState } from '@/favorites/states/isFavoriteFolderCreatingState';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { IconPlus, MenuItem } from 'twenty-ui';
|
||||
|
||||
const StyledFooter = styled.div`
|
||||
background: ${({ theme }) => theme.background.primary};
|
||||
border-bottom-left-radius: ${({ theme }) => theme.border.radius.md};
|
||||
border-bottom-right-radius: ${({ theme }) => theme.border.radius.md};
|
||||
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,
|
||||
);
|
||||
const theme = useTheme();
|
||||
const { closeDropdown } = useDropdown(FAVORITE_FOLDER_PICKER_DROPDOWN_ID);
|
||||
|
||||
return (
|
||||
<StyledFooter>
|
||||
<DropdownMenuItemsContainer>
|
||||
<MenuItem
|
||||
className="add-folder"
|
||||
onClick={() => {
|
||||
setIsFavoriteFolderCreating(true);
|
||||
closeDropdown();
|
||||
}}
|
||||
text="Add folder"
|
||||
LeftIcon={() => <StyledIconPlus size={theme.icon.size.md} />}
|
||||
/>
|
||||
</DropdownMenuItemsContainer>
|
||||
</StyledFooter>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,74 @@
|
||||
import { favoriteFolderPickerCheckedComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFolderPickerCheckedComponentState';
|
||||
import { favoriteFolderSearchFilterComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFoldersSearchFilterComponentState';
|
||||
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';
|
||||
|
||||
const StyledItemsContainer = styled.div`
|
||||
width: 100%;
|
||||
`;
|
||||
|
||||
const StyledDropdownMenuSeparator = styled(DropdownMenuSeparator)`
|
||||
margin-bottom: ${({ theme }) => theme.spacing(1)};
|
||||
margin-top: ${({ theme }) => theme.spacing(1)};
|
||||
`;
|
||||
|
||||
type FavoriteFolderPickerListProps = {
|
||||
folders: FavoriteFolder[];
|
||||
toggleFolderSelection: (folderId: string) => void;
|
||||
};
|
||||
|
||||
export const NO_FOLDER_ID = 'no-folder';
|
||||
|
||||
export const FavoriteFolderPickerList = ({
|
||||
folders,
|
||||
toggleFolderSelection,
|
||||
}: FavoriteFolderPickerListProps) => {
|
||||
const [favoriteFoldersSearchFilter] = useRecoilComponentStateV2(
|
||||
favoriteFolderSearchFilterComponentState,
|
||||
);
|
||||
const [favoriteFolderPickerChecked] = useRecoilComponentStateV2(
|
||||
favoriteFolderPickerCheckedComponentState,
|
||||
);
|
||||
|
||||
const filteredFolders = folders.filter((folder) =>
|
||||
folder.name
|
||||
.toLowerCase()
|
||||
.includes(favoriteFoldersSearchFilter.toLowerCase()),
|
||||
);
|
||||
|
||||
const showNoFolderOption =
|
||||
!favoriteFoldersSearchFilter ||
|
||||
'no folder'.includes(favoriteFoldersSearchFilter.toLowerCase());
|
||||
|
||||
return (
|
||||
<StyledItemsContainer>
|
||||
{showNoFolderOption && (
|
||||
<FavoriteFolderMenuItemMultiSelect
|
||||
key={`menu-${NO_FOLDER_ID}`}
|
||||
onSelectChange={() => toggleFolderSelection(NO_FOLDER_ID)}
|
||||
selected={favoriteFolderPickerChecked.includes(NO_FOLDER_ID)}
|
||||
text="No folder"
|
||||
className="no-folder-menu-item-multi-select"
|
||||
/>
|
||||
)}
|
||||
{showNoFolderOption && filteredFolders.length > 0 && (
|
||||
<StyledDropdownMenuSeparator />
|
||||
)}
|
||||
{filteredFolders.length > 0
|
||||
? filteredFolders.map((folder) => (
|
||||
<FavoriteFolderMenuItemMultiSelect
|
||||
key={`menu-${folder.id}`}
|
||||
onSelectChange={() => toggleFolderSelection(folder.id)}
|
||||
selected={favoriteFolderPickerChecked.includes(folder.id)}
|
||||
text={folder.name}
|
||||
className="folder-menu-item-multi-select"
|
||||
/>
|
||||
))
|
||||
: !showNoFolderOption && <MenuItem text="No folders found" />}
|
||||
</StyledItemsContainer>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,31 @@
|
||||
import { favoriteFolderSearchFilterComponentState } from '@/favorites/favorite-folder-picker/states/favoriteFoldersSearchFilterComponentState';
|
||||
import { DropdownMenuSearchInput } from '@/ui/layout/dropdown/components/DropdownMenuSearchInput';
|
||||
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
|
||||
import { useCallback } from 'react';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
|
||||
export const FavoriteFolderPickerSearchInput = () => {
|
||||
const [favoriteFoldersSearchFilter, setFavoriteFoldersSearchFilter] =
|
||||
useRecoilComponentStateV2(favoriteFolderSearchFilterComponentState);
|
||||
|
||||
const debouncedSetSearchFilter = useDebouncedCallback(
|
||||
setFavoriteFoldersSearchFilter,
|
||||
100,
|
||||
{ leading: true },
|
||||
);
|
||||
|
||||
const handleFilterChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
debouncedSetSearchFilter(event.currentTarget.value);
|
||||
},
|
||||
[debouncedSetSearchFilter],
|
||||
);
|
||||
|
||||
return (
|
||||
<DropdownMenuSearchInput
|
||||
value={favoriteFoldersSearchFilter}
|
||||
onChange={handleFilterChange}
|
||||
autoFocus
|
||||
/>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,2 @@
|
||||
export const FAVORITE_FOLDER_PICKER_DROPDOWN_ID =
|
||||
'favorite-folder-picker-dropdown';
|
||||
@ -0,0 +1,129 @@
|
||||
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 { useCreateFavorite } from '@/favorites/hooks/useCreateFavorite';
|
||||
import { useDeleteFavorite } from '@/favorites/hooks/useDeleteFavorite';
|
||||
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 { useRecoilCallback } from 'recoil';
|
||||
import { isDefined } from 'twenty-ui';
|
||||
|
||||
type useFavoriteFolderPickerProps = {
|
||||
record?: ObjectRecord;
|
||||
objectNameSingular: string;
|
||||
};
|
||||
|
||||
type FolderOperations = {
|
||||
getFoldersByIds: () => FavoriteFolder[];
|
||||
toggleFolderSelection: (folderId: string) => Promise<void>;
|
||||
};
|
||||
|
||||
export const useFavoriteFolderPicker = ({
|
||||
record,
|
||||
objectNameSingular,
|
||||
}: useFavoriteFolderPickerProps): FolderOperations => {
|
||||
const [favoriteFolderIdsPicker] = useRecoilComponentStateV2(
|
||||
favoriteFolderIdsPickerComponentState,
|
||||
);
|
||||
|
||||
const favoriteFoldersMultiSelectCheckedState =
|
||||
useRecoilComponentCallbackStateV2(
|
||||
favoriteFolderPickerCheckedComponentState,
|
||||
);
|
||||
|
||||
const favoriteFolderPickerFamilyState = useRecoilComponentCallbackStateV2(
|
||||
favoriteFolderPickerComponentFamilyState,
|
||||
);
|
||||
|
||||
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 toggleFolderSelection = useRecoilCallback(
|
||||
({ snapshot, set }) =>
|
||||
async (folderId: string) => {
|
||||
const targetId = record?.id;
|
||||
const targetObject = record;
|
||||
|
||||
if (!isDefined(targetObject) || !isDefined(targetId)) {
|
||||
throw new Error(
|
||||
`Cannot toggle folder selection: record ${
|
||||
!isDefined(targetObject) ? 'object' : 'id'
|
||||
} is not defined`,
|
||||
);
|
||||
}
|
||||
|
||||
const deleteFavoriteForRecord = async (isUnorganized: boolean) => {
|
||||
const favoriteToDelete = favorites.find(
|
||||
(favorite) =>
|
||||
favorite.recordId === targetId &&
|
||||
(isUnorganized
|
||||
? !favorite.favoriteFolderId
|
||||
: favorite.favoriteFolderId === folderId),
|
||||
);
|
||||
|
||||
if (!isDefined(favoriteToDelete)) {
|
||||
return;
|
||||
}
|
||||
|
||||
await deleteFavorite(favoriteToDelete.id);
|
||||
};
|
||||
|
||||
const checkedIds = snapshot
|
||||
.getLoadable(favoriteFoldersMultiSelectCheckedState)
|
||||
.getValue();
|
||||
|
||||
const isAlreadyChecked = checkedIds.includes(folderId);
|
||||
|
||||
if (isAlreadyChecked) {
|
||||
await deleteFavoriteForRecord(folderId === 'no-folder');
|
||||
|
||||
const newCheckedIds = checkedIds.filter((id) => id !== folderId);
|
||||
set(favoriteFoldersMultiSelectCheckedState, newCheckedIds);
|
||||
return;
|
||||
}
|
||||
|
||||
const folderIdToUse = folderId === 'no-folder' ? undefined : folderId;
|
||||
|
||||
if (isDefined(record)) {
|
||||
await createFavorite(record, objectNameSingular, folderIdToUse);
|
||||
}
|
||||
|
||||
const newCheckedIds = [...checkedIds, folderId];
|
||||
set(favoriteFoldersMultiSelectCheckedState, newCheckedIds);
|
||||
},
|
||||
[
|
||||
favoriteFoldersMultiSelectCheckedState,
|
||||
createFavorite,
|
||||
deleteFavorite,
|
||||
favorites,
|
||||
record,
|
||||
objectNameSingular,
|
||||
],
|
||||
);
|
||||
|
||||
return {
|
||||
getFoldersByIds,
|
||||
toggleFolderSelection,
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,20 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
type FavoriteFolderPickerScopeProps = {
|
||||
children: ReactNode;
|
||||
favoriteFoldersScopeId: string;
|
||||
};
|
||||
|
||||
export const FavoriteFolderPickerScope = ({
|
||||
children,
|
||||
favoriteFoldersScopeId,
|
||||
}: FavoriteFolderPickerScopeProps) => {
|
||||
return (
|
||||
<FavoriteFolderPickerInstanceContext.Provider
|
||||
value={{ instanceId: favoriteFoldersScopeId }}
|
||||
>
|
||||
{children}
|
||||
</FavoriteFolderPickerInstanceContext.Provider>
|
||||
);
|
||||
};
|
||||
@ -0,0 +1,4 @@
|
||||
import { createComponentInstanceContext } from '@/ui/utilities/state/component-state/utils/createComponentInstanceContext';
|
||||
|
||||
export const FavoriteFolderPickerInstanceContext =
|
||||
createComponentInstanceContext();
|
||||
@ -0,0 +1,10 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const favoriteFolderIdsPickerComponentState = createComponentStateV2<
|
||||
string[]
|
||||
>({
|
||||
key: 'favoriteFolderIdsPickerComponentState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: FavoriteFolderPickerInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,9 @@
|
||||
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,10 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const favoriteFolderPickerCheckedComponentState = createComponentStateV2<
|
||||
string[]
|
||||
>({
|
||||
key: 'favoriteFolderPickerCheckedComponentState',
|
||||
defaultValue: [],
|
||||
componentInstanceContext: FavoriteFolderPickerInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,10 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { FavoriteFolder } from '@/favorites/types/FavoriteFolder';
|
||||
import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2';
|
||||
|
||||
export const favoriteFolderPickerComponentFamilyState =
|
||||
createComponentFamilyStateV2<FavoriteFolder | undefined, string>({
|
||||
key: 'favoriteFolderPickerComponentFamilyState',
|
||||
defaultValue: undefined,
|
||||
componentInstanceContext: FavoriteFolderPickerInstanceContext,
|
||||
});
|
||||
@ -0,0 +1,9 @@
|
||||
import { FavoriteFolderPickerInstanceContext } from '@/favorites/favorite-folder-picker/states/context/FavoriteFolderPickerInstanceContext';
|
||||
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
|
||||
|
||||
export const favoriteFolderSearchFilterComponentState =
|
||||
createComponentStateV2<string>({
|
||||
key: 'favoriteFolderSearchFilterComponentState',
|
||||
defaultValue: '',
|
||||
componentInstanceContext: FavoriteFolderPickerInstanceContext,
|
||||
});
|
||||
Reference in New Issue
Block a user