Favorites Drag and Drop Implementation (#8979)
Adds drag and drop functionality for favorites management, allowing users to: - Move favorites between folders - Move favorites from folders to orphan section - Move orphan favorites into folders Known Issues: Drop detection at folder boundaries requires spacing workaround
This commit is contained in:
@ -0,0 +1,17 @@
|
||||
import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds';
|
||||
import { createFolderDroppableId } from '../createFolderDroppableId';
|
||||
|
||||
describe('createFolderDroppableId', () => {
|
||||
it('should create a valid folder droppable id', () => {
|
||||
const folderId = '123-456';
|
||||
const result = createFolderDroppableId(folderId);
|
||||
|
||||
expect(result).toBe(`${FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX}${folderId}`);
|
||||
});
|
||||
|
||||
it('should work with empty string', () => {
|
||||
const result = createFolderDroppableId('');
|
||||
|
||||
expect(result).toBe(FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,19 @@
|
||||
import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds';
|
||||
import { createFolderHeaderDroppableId } from '../createFolderHeaderDroppableId';
|
||||
|
||||
describe('createFolderHeaderDroppableId', () => {
|
||||
it('should create a valid folder header droppable id', () => {
|
||||
const folderId = '123-456';
|
||||
const result = createFolderHeaderDroppableId(folderId);
|
||||
|
||||
expect(result).toBe(
|
||||
`${FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX}${folderId}`,
|
||||
);
|
||||
});
|
||||
|
||||
it('should work with empty string', () => {
|
||||
const result = createFolderHeaderDroppableId('');
|
||||
|
||||
expect(result).toBe(FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,47 @@
|
||||
import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds';
|
||||
import { validateAndExtractFolderId } from '../validateAndExtractFolderId';
|
||||
|
||||
describe('validateAndExtractFolderId', () => {
|
||||
it('should return null for orphan favorites', () => {
|
||||
const result = validateAndExtractFolderId(
|
||||
FAVORITE_DROPPABLE_IDS.ORPHAN_FAVORITES,
|
||||
);
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it('should extract folder id from folder droppable id', () => {
|
||||
const folderId = '123-456';
|
||||
const droppableId = `${FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX}${folderId}`;
|
||||
|
||||
const result = validateAndExtractFolderId(droppableId);
|
||||
expect(result).toBe(folderId);
|
||||
});
|
||||
|
||||
it('should extract folder id from folder header droppable id', () => {
|
||||
const folderId = '123-456';
|
||||
const droppableId = `${FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX}${folderId}`;
|
||||
|
||||
const result = validateAndExtractFolderId(droppableId);
|
||||
expect(result).toBe(folderId);
|
||||
});
|
||||
|
||||
it('should throw error for invalid droppable id format', () => {
|
||||
expect(() => {
|
||||
validateAndExtractFolderId('invalid-id');
|
||||
}).toThrow('Invalid droppable ID format: invalid-id');
|
||||
});
|
||||
|
||||
it('should throw error for empty folder id in folder format', () => {
|
||||
expect(() => {
|
||||
validateAndExtractFolderId(FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX);
|
||||
}).toThrow(`Invalid folder ID: ${FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX}`);
|
||||
});
|
||||
|
||||
it('should throw error for empty folder id in folder header format', () => {
|
||||
expect(() => {
|
||||
validateAndExtractFolderId(FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX);
|
||||
}).toThrow(
|
||||
`Invalid folder header ID: ${FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX}`,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,6 @@
|
||||
import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds';
|
||||
import { FavoriteDroppableId } from '@/favorites/types/FavoriteDroppableId';
|
||||
|
||||
export const createFolderDroppableId = (
|
||||
folderId: string,
|
||||
): FavoriteDroppableId => `${FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX}${folderId}`;
|
||||
@ -0,0 +1,7 @@
|
||||
import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds';
|
||||
import { FavoriteDroppableId } from '@/favorites/types/FavoriteDroppableId';
|
||||
|
||||
export const createFolderHeaderDroppableId = (
|
||||
folderId: string,
|
||||
): FavoriteDroppableId =>
|
||||
`${FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX}${folderId}`;
|
||||
@ -0,0 +1,29 @@
|
||||
import { FAVORITE_DROPPABLE_IDS } from '@/favorites/constants/FavoriteDroppableIds';
|
||||
|
||||
export const validateAndExtractFolderId = (
|
||||
droppableId: string,
|
||||
): string | null => {
|
||||
if (droppableId === FAVORITE_DROPPABLE_IDS.ORPHAN_FAVORITES) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (droppableId.startsWith(FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX)) {
|
||||
const folderId = droppableId.replace(
|
||||
FAVORITE_DROPPABLE_IDS.FOLDER_HEADER_PREFIX,
|
||||
'',
|
||||
);
|
||||
if (!folderId) throw new Error(`Invalid folder header ID: ${droppableId}`);
|
||||
return folderId;
|
||||
}
|
||||
|
||||
if (droppableId.startsWith(FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX)) {
|
||||
const folderId = droppableId.replace(
|
||||
FAVORITE_DROPPABLE_IDS.FOLDER_PREFIX,
|
||||
'',
|
||||
);
|
||||
if (!folderId) throw new Error(`Invalid folder ID: ${droppableId}`);
|
||||
return folderId;
|
||||
}
|
||||
|
||||
throw new Error(`Invalid droppable ID format: ${droppableId}`);
|
||||
};
|
||||
Reference in New Issue
Block a user