Skip to content

Commit

Permalink
fixed folder issues
Browse files Browse the repository at this point in the history
  • Loading branch information
IlyaBondar committed Feb 9, 2024
1 parent a0ff30a commit 5c87d66
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 62 deletions.
85 changes: 36 additions & 49 deletions apps/chat/src/store/conversations/conversations.epics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ import {
getFolderFromPath,
getFoldersFromPaths,
getNextDefaultName,
updateMovedEntityId,
updateMovedFolderId,
} from '@/src/utils/app/folders';
import {
mergeMessages,
Expand All @@ -69,7 +71,7 @@ import {
Role,
} from '@/src/types/chat';
import { EntityType, FeatureType, UploadStatus } from '@/src/types/common';
import { FolderType } from '@/src/types/folder';
import { FolderInterface, FolderType } from '@/src/types/folder';
import { AppEpic } from '@/src/types/store';

import { resetShareEntity } from '@/src/constants/chat';
Expand All @@ -90,8 +92,6 @@ import {
ConversationsSelectors,
} from './conversations.reducers';

import escapeStringRegexp from 'escape-string-regexp';

const initEpic: AppEpic = (action$) =>
action$.pipe(
filter((action) => ConversationsActions.init.match(action)),
Expand Down Expand Up @@ -523,6 +523,17 @@ const updateFolderEpic: AppEpic = (action$, state$) =>

return ConversationService.getConversations(payload.folderId, true).pipe(
switchMap((conversations) => {
const updateFolderId = updateMovedFolderId.bind(
null,
payload.folderId,
newFolder.id,
);
const updateEntityId = updateMovedEntityId.bind(
null,
payload.folderId,
newFolder.id,
);

const folders = ConversationsSelectors.selectFolders(state$.value);
const allConversations = ConversationsSelectors.selectConversations(
state$.value,
Expand All @@ -534,67 +545,46 @@ const updateFolderEpic: AppEpic = (action$, state$) =>
const selectedConversationsIds =
ConversationsSelectors.selectSelectedConversationsIds(state$.value);

const regex = new RegExp(`^${escapeStringRegexp(payload.folderId)}`);
const allFolderIds = conversations.map(
(conv) => conv.folderId as string,
);

const newUniqueFolderIds = Array.from(
new Set(conversations.map((conv) => conv.folderId as string)),
).map((id) => id.replace(regex, newFolder.id));
const updatedExistedFolders = folders.map((f: FolderInterface) => ({
...f,
id: updateFolderId(f.id)!,
folderId: updateFolderId(f.folderId),
}));

const allNewFolderIdsSet = new Set(
newUniqueFolderIds.flatMap((fid) => getAllPathsFromPath(fid)),
);
const allNewFolderIds = Array.from(allNewFolderIdsSet);
const oldFolderIds = new Set(
folders
.filter(
(folder) =>
folder.id === payload.folderId || // this old folder
folder.id.startsWith(`${payload.folderId}/`), // child folders
)
.map((f) => f.id),
const newUniqueFolderIds = Array.from(new Set(allFolderIds)).map(
(id) => updateFolderId(id),
);

const updatedFolders = combineEntities(
getFoldersFromPaths(allNewFolderIds, FolderType.Chat),
folders.map((folder) =>
oldFolderIds.has(folder.id)
? {
...folder,
id: folder.id.replace(regex, newFolder.id),
folderId: folder.folderId?.replace(regex, newFolder.id),
}
: folder,
),
getFoldersFromPaths(newUniqueFolderIds, FolderType.Chat),
updatedExistedFolders,
);

const updatedConversations = combineEntities(
allConversations.map((conv) =>
conv.id.startsWith(`${payload.folderId}/`)
? addGeneratedConversationId({
...conv,
folderId: conv.folderId?.replace(regex, newFolder.id),
})
: conv,
), // child chats
addGeneratedConversationId({
...conv,
folderId: updateFolderId(conv.folderId),
}),
),
conversations.map((conv) =>
addGeneratedConversationId({
...conv,
folderId: conv.folderId?.replace(regex, newFolder.id),
folderId: updateFolderId(conv.folderId),
}),
),
);

const updatedOpenedFoldersIds = openedFoldersIds.map((id) =>
id === payload.folderId || id.startsWith(`${payload.folderId}/`)
? id.replace(regex, newFolder.id)
: id,
const updatedOpenedFoldersIds = openedFoldersIds.map(
(id) => updateFolderId(id)!,
);

const updatedSelectedConversationsIds = selectedConversationsIds.map(
(id) =>
id.startsWith(`${payload.folderId}/`)
? id.replace(regex, newFolder.id)
: id,
(id) => updateEntityId(id),
);

const actions: Observable<AnyAction>[] = [];
Expand All @@ -620,10 +610,7 @@ const updateFolderEpic: AppEpic = (action$, state$) =>
ConversationsActions.updateConversation({
id: conversation.id,
values: {
folderId: conversation.folderId?.replace(
regex,
newFolder.id,
),
folderId: updateFolderId(conversation.folderId),
},
}),
),
Expand Down
17 changes: 6 additions & 11 deletions apps/chat/src/store/conversations/conversations.reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -642,9 +642,7 @@ export const conversationsSlice = createSlice({
(id) => !payload.paths.has(id),
);
state.foldersStatus = UploadStatus.LOADED;
state.folders = payload.folders.concat(
state.folders.filter((folder) => !payload.paths.has(folder.folderId)),
);
state.folders = combineEntities(payload.folders, state.folders);
},
uploadFoldersFail: (
state,
Expand Down Expand Up @@ -683,20 +681,17 @@ export const conversationsSlice = createSlice({
return map;
}, new Map<string, ConversationInfo>());

state.conversations = payload.conversations
.map((conv) =>
state.conversations = combineEntities(
payload.conversations.map((conv) =>
payload.paths.has(conv.folderId)
? {
...conversationMap.get(conv.id),
...conv,
}
: conv,
)
.concat(
state.conversations.filter(
(conv) => !payload.paths.has(conv.folderId),
),
);
),
state.conversations,
);
state.conversationsStatus = UploadStatus.LOADED;
},
uploadConversationsFail: (state) => {
Expand Down
55 changes: 54 additions & 1 deletion apps/chat/src/utils/app/__tests__/folders.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { FolderType } from '@/src/types/folder';

import { getFolderIdByPath } from '../folders';
import {
getFolderIdByPath,
updateMovedEntityId,
updateMovedFolderId,
} from '../folders';

describe('Folder utility methods', () => {
it.each([
Expand All @@ -20,4 +24,53 @@ describe('Folder utility methods', () => {
];
expect(getFolderIdByPath(path, folders)).toBe(expectedFolderId);
});

it.each([
[undefined, 'f1', undefined, 'f1'],
['f1', 'f2', 'f1', 'f2'],
['f1', undefined, 'f1', undefined],
['f1', undefined, 'f1/f2', 'f2'],
['f1', undefined, 'f1/f1/f1', 'f1/f1'],
[undefined, undefined, 'f1/f1/f1', 'f1/f1/f1'],
[undefined, 'f3', 'f1/f1/f1', 'f1/f1/f1'],
['f2', undefined, 'f1/f1/f1', 'f1/f1/f1'],
['f2', 'f3', 'f1/f1/f1', 'f1/f1/f1'],
])(
'updateMovedFolderId (%s, %s, %s, %s)',
(
oldParentFolderId: string | undefined,
newParentFolderId: string | undefined,
currentId: string | undefined,
expectedFolderId: string | undefined,
) => {
expect(
updateMovedFolderId(oldParentFolderId, newParentFolderId, currentId),
).toBe(expectedFolderId);
},
);

it.each([
['f1', 'f2', 'f1', 'f1'],
['f1', 'f2', 'f1/f1', 'f2/f1'],
['f1/f1', 'f2', 'f1/f1/f1', 'f2/f1'],
['f1', undefined, 'f1', 'f1'],
['f1', undefined, 'f1/f2', 'f2'],
['f1', undefined, 'f1/f1/f1', 'f1/f1'],
[undefined, undefined, 'f1/f1/f1', 'f1/f1/f1'],
[undefined, 'f3', 'f1/f1/f1', 'f1/f1/f1'],
['f2', undefined, 'f1/f1/f1', 'f1/f1/f1'],
['f2', 'f3', 'f1/f1/f1', 'f1/f1/f1'],
])(
'updateMovedEntityId (%s, %s, %s, %s)',
(
oldParentFolderId: string | undefined,
newParentFolderId: string | undefined,
currentId: string,
expectedFolderId: string,
) => {
expect(
updateMovedEntityId(oldParentFolderId, newParentFolderId, currentId),
).toBe(expectedFolderId);
},
);
});
36 changes: 36 additions & 0 deletions apps/chat/src/utils/app/folders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -421,3 +421,39 @@ export const compareEntitiesByName = <
}
return 0;
};

export const updateMovedFolderId = (
oldParentFolderId: string | undefined,
newParentFolderId: string | undefined,
folderId: string | undefined,
) => {
const curr = folderId || '';
const old = oldParentFolderId || '';
if (curr === old) {
return newParentFolderId;
}
const prefix = `${old}/`;
if (curr.startsWith(prefix)) {
if (!newParentFolderId) {
return curr.replace(prefix, '') || undefined;
}
return curr.replace(old, newParentFolderId);
}
return folderId;
};

export const updateMovedEntityId = (
oldParentFolderId: string | undefined,
newParentFolderId: string | undefined,
entityId: string,
): string => {
const old = oldParentFolderId || '';
const prefix = `${old}/`;
if (entityId.startsWith(prefix)) {
if (!newParentFolderId) {
return entityId.replace(prefix, '');
}
return entityId.replace(old, newParentFolderId);
}
return entityId;
};
5 changes: 4 additions & 1 deletion nx.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
},
"test": {
"executor": "@nx/vite:test",
"outputs": ["{options.reportsDirectory}"]
"outputs": ["{options.reportsDirectory}"],
"options": {
"watch": true
}
},
"test:coverage": {
"executor": "@nx/vite:test",
Expand Down

0 comments on commit 5c87d66

Please sign in to comment.