Add syncable NavigationMenuItem entity to core schema (#17232)
Implements a new syncable `navigationMenuItem` entity in the core schema to replace the workspace `favorite` entity. ## Next Steps - Frontend integration ([separate PR](https://github.com/twentyhq/twenty/pull/17268)) - Data migration (separate PR)
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
|
||||
export const FLAT_NAVIGATION_MENU_ITEM_EDITABLE_PROPERTIES = [
|
||||
'position',
|
||||
'folderId',
|
||||
'name',
|
||||
] as const satisfies (keyof FlatNavigationMenuItem)[];
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { WorkspaceFlatNavigationMenuItemMapCacheService } from 'src/engine/metadata-modules/flat-navigation-menu-item/services/workspace-flat-navigation-menu-item-map-cache.service';
|
||||
import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
TypeOrmModule.forFeature([NavigationMenuItemEntity]),
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
],
|
||||
providers: [WorkspaceFlatNavigationMenuItemMapCacheService],
|
||||
exports: [WorkspaceFlatNavigationMenuItemMapCacheService],
|
||||
})
|
||||
export class FlatNavigationMenuItemModule {}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { WorkspaceCacheProvider } from 'src/engine/workspace-cache/interfaces/workspace-cache-provider.service';
|
||||
|
||||
import { createEmptyFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-flat-entity-maps.constant';
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { addFlatNavigationMenuItemToMapsAndUpdateIndex } from 'src/engine/metadata-modules/flat-navigation-menu-item/utils/add-flat-navigation-menu-item-to-maps-and-update-index.util';
|
||||
import { fromNavigationMenuItemEntityToFlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/utils/from-navigation-menu-item-entity-to-flat-navigation-menu-item.util';
|
||||
import { NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity';
|
||||
import { WorkspaceCache } from 'src/engine/workspace-cache/decorators/workspace-cache.decorator';
|
||||
|
||||
@Injectable()
|
||||
@WorkspaceCache('flatNavigationMenuItemMaps')
|
||||
export class WorkspaceFlatNavigationMenuItemMapCacheService extends WorkspaceCacheProvider<FlatNavigationMenuItemMaps> {
|
||||
constructor(
|
||||
@InjectRepository(NavigationMenuItemEntity)
|
||||
private readonly navigationMenuItemRepository: Repository<NavigationMenuItemEntity>,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async computeForCache(
|
||||
workspaceId: string,
|
||||
): Promise<FlatNavigationMenuItemMaps> {
|
||||
const navigationMenuItems = await this.navigationMenuItemRepository.find({
|
||||
where: { workspaceId },
|
||||
withDeleted: true,
|
||||
});
|
||||
|
||||
const flatNavigationMenuItemMaps = {
|
||||
...createEmptyFlatEntityMaps(),
|
||||
byUserWorkspaceIdAndFolderId: {},
|
||||
};
|
||||
|
||||
for (const navigationMenuItemEntity of navigationMenuItems) {
|
||||
const flatNavigationMenuItem =
|
||||
fromNavigationMenuItemEntityToFlatNavigationMenuItem(
|
||||
navigationMenuItemEntity,
|
||||
);
|
||||
|
||||
addFlatNavigationMenuItemToMapsAndUpdateIndex({
|
||||
flatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
});
|
||||
}
|
||||
|
||||
return flatNavigationMenuItemMaps;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
|
||||
export type FlatNavigationMenuItemMaps =
|
||||
FlatEntityMaps<FlatNavigationMenuItem> & {
|
||||
byUserWorkspaceIdAndFolderId: Partial<
|
||||
Record<string, Partial<Record<string, FlatNavigationMenuItem[]>>>
|
||||
>;
|
||||
};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import { type FlatEntityFrom } from 'src/engine/metadata-modules/flat-entity/types/flat-entity.type';
|
||||
import { type NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity';
|
||||
|
||||
export type FlatNavigationMenuItem = FlatEntityFrom<NavigationMenuItemEntity>;
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { addFlatEntityToFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/add-flat-entity-to-flat-entity-maps-through-mutation-or-throw.util';
|
||||
|
||||
export const addFlatNavigationMenuItemToMapsAndUpdateIndex = ({
|
||||
flatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
}: {
|
||||
flatNavigationMenuItem: FlatNavigationMenuItem;
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
}): void => {
|
||||
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
|
||||
flatEntity: flatNavigationMenuItem,
|
||||
flatEntityMapsToMutate: flatNavigationMenuItemMaps,
|
||||
});
|
||||
|
||||
const userWorkspaceIdKey = flatNavigationMenuItem.userWorkspaceId ?? 'null';
|
||||
const folderIdKey = flatNavigationMenuItem.folderId ?? 'null';
|
||||
|
||||
if (
|
||||
!flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[userWorkspaceIdKey]
|
||||
) {
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
userWorkspaceIdKey
|
||||
] = {};
|
||||
}
|
||||
|
||||
if (
|
||||
!flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
userWorkspaceIdKey
|
||||
][folderIdKey]
|
||||
) {
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[userWorkspaceIdKey][
|
||||
folderIdKey
|
||||
] = [];
|
||||
}
|
||||
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[userWorkspaceIdKey][
|
||||
folderIdKey
|
||||
].push(flatNavigationMenuItem);
|
||||
};
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { removeFlatNavigationMenuItemFromIndex } from 'src/engine/metadata-modules/flat-navigation-menu-item/utils/remove-flat-navigation-menu-item-from-index.util';
|
||||
import { deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/delete-flat-entity-from-flat-entity-maps-through-mutation-or-throw.util';
|
||||
|
||||
export const deleteFlatNavigationMenuItemFromMapsAndIndex = ({
|
||||
flatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
}: {
|
||||
flatNavigationMenuItem: FlatNavigationMenuItem;
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
}): void => {
|
||||
removeFlatNavigationMenuItemFromIndex({
|
||||
flatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
});
|
||||
|
||||
deleteFlatEntityFromFlatEntityMapsThroughMutationOrThrow({
|
||||
entityToDeleteId: flatNavigationMenuItem.id,
|
||||
flatEntityMapsToMutate: flatNavigationMenuItemMaps,
|
||||
});
|
||||
};
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { type CreateNavigationMenuItemInput } from 'src/engine/metadata-modules/navigation-menu-item/dtos/create-navigation-menu-item.input';
|
||||
|
||||
export const fromCreateNavigationMenuItemInputToFlatNavigationMenuItemToCreate =
|
||||
({
|
||||
createNavigationMenuItemInput,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
flatNavigationMenuItemMaps,
|
||||
}: {
|
||||
createNavigationMenuItemInput: CreateNavigationMenuItemInput;
|
||||
workspaceId: string;
|
||||
applicationId: string;
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
}): FlatNavigationMenuItem => {
|
||||
const id = uuidv4();
|
||||
const now = new Date().toISOString();
|
||||
|
||||
let position = createNavigationMenuItemInput.position;
|
||||
|
||||
if (!isDefined(position)) {
|
||||
const userWorkspaceIdKey =
|
||||
createNavigationMenuItemInput.userWorkspaceId ?? 'null';
|
||||
const folderIdKey = createNavigationMenuItemInput.folderId ?? 'null';
|
||||
|
||||
const existingItems =
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
userWorkspaceIdKey
|
||||
]?.[folderIdKey] ?? [];
|
||||
|
||||
const maxPosition = existingItems.reduce(
|
||||
(max, item) => Math.max(max, item.position),
|
||||
0,
|
||||
);
|
||||
|
||||
position = maxPosition + 1;
|
||||
}
|
||||
|
||||
return {
|
||||
id,
|
||||
universalIdentifier: id,
|
||||
userWorkspaceId: createNavigationMenuItemInput.userWorkspaceId ?? null,
|
||||
targetRecordId: createNavigationMenuItemInput.targetRecordId ?? null,
|
||||
targetObjectMetadataId:
|
||||
createNavigationMenuItemInput.targetObjectMetadataId ?? null,
|
||||
viewId: createNavigationMenuItemInput.viewId ?? null,
|
||||
folderId: createNavigationMenuItemInput.folderId ?? null,
|
||||
name: createNavigationMenuItemInput.name ?? null,
|
||||
position,
|
||||
workspaceId,
|
||||
applicationId,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
};
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import {
|
||||
NavigationMenuItemException,
|
||||
NavigationMenuItemExceptionCode,
|
||||
} from 'src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.exception';
|
||||
|
||||
export const fromDeleteNavigationMenuItemInputToFlatNavigationMenuItemOrThrow =
|
||||
({
|
||||
flatNavigationMenuItemMaps,
|
||||
navigationMenuItemId,
|
||||
}: {
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
navigationMenuItemId: string;
|
||||
}): FlatNavigationMenuItem => {
|
||||
const existingFlatNavigationMenuItem = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: navigationMenuItemId,
|
||||
flatEntityMaps: flatNavigationMenuItemMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatNavigationMenuItem)) {
|
||||
throw new NavigationMenuItemException(
|
||||
'Navigation menu item not found',
|
||||
NavigationMenuItemExceptionCode.NAVIGATION_MENU_ITEM_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
return existingFlatNavigationMenuItem;
|
||||
};
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { type NavigationMenuItemDTO } from 'src/engine/metadata-modules/navigation-menu-item/dtos/navigation-menu-item.dto';
|
||||
|
||||
export const fromFlatNavigationMenuItemToNavigationMenuItemDto = (
|
||||
flatNavigationMenuItem: FlatNavigationMenuItem,
|
||||
): NavigationMenuItemDTO => ({
|
||||
id: flatNavigationMenuItem.id,
|
||||
userWorkspaceId: flatNavigationMenuItem.userWorkspaceId ?? undefined,
|
||||
targetRecordId: flatNavigationMenuItem.targetRecordId ?? undefined,
|
||||
targetObjectMetadataId:
|
||||
flatNavigationMenuItem.targetObjectMetadataId ?? undefined,
|
||||
viewId: flatNavigationMenuItem.viewId ?? undefined,
|
||||
folderId: flatNavigationMenuItem.folderId ?? undefined,
|
||||
name: flatNavigationMenuItem.name ?? undefined,
|
||||
position: flatNavigationMenuItem.position,
|
||||
workspaceId: flatNavigationMenuItem.workspaceId,
|
||||
applicationId: flatNavigationMenuItem.applicationId ?? undefined,
|
||||
createdAt: new Date(flatNavigationMenuItem.createdAt),
|
||||
updatedAt: new Date(flatNavigationMenuItem.updatedAt),
|
||||
});
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { type NavigationMenuItemEntity } from 'src/engine/metadata-modules/navigation-menu-item/entities/navigation-menu-item.entity';
|
||||
|
||||
export const fromNavigationMenuItemEntityToFlatNavigationMenuItem = (
|
||||
navigationMenuItemEntity: NavigationMenuItemEntity,
|
||||
): FlatNavigationMenuItem => {
|
||||
return {
|
||||
id: navigationMenuItemEntity.id,
|
||||
userWorkspaceId: navigationMenuItemEntity.userWorkspaceId,
|
||||
targetRecordId: navigationMenuItemEntity.targetRecordId,
|
||||
targetObjectMetadataId: navigationMenuItemEntity.targetObjectMetadataId,
|
||||
viewId: navigationMenuItemEntity.viewId,
|
||||
folderId: navigationMenuItemEntity.folderId,
|
||||
name: navigationMenuItemEntity.name,
|
||||
position: navigationMenuItemEntity.position,
|
||||
workspaceId: navigationMenuItemEntity.workspaceId,
|
||||
universalIdentifier: navigationMenuItemEntity.universalIdentifier,
|
||||
applicationId: navigationMenuItemEntity.applicationId,
|
||||
createdAt: navigationMenuItemEntity.createdAt.toISOString(),
|
||||
updatedAt: navigationMenuItemEntity.updatedAt.toISOString(),
|
||||
};
|
||||
};
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import { FLAT_NAVIGATION_MENU_ITEM_EDITABLE_PROPERTIES } from 'src/engine/metadata-modules/flat-navigation-menu-item/constants/flat-navigation-menu-item-editable-properties.constant';
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { type UpdateNavigationMenuItemInput } from 'src/engine/metadata-modules/navigation-menu-item/dtos/update-navigation-menu-item.input';
|
||||
import {
|
||||
NavigationMenuItemException,
|
||||
NavigationMenuItemExceptionCode,
|
||||
} from 'src/engine/metadata-modules/navigation-menu-item/navigation-menu-item.exception';
|
||||
import { mergeUpdateInExistingRecord } from 'src/utils/merge-update-in-existing-record.util';
|
||||
|
||||
export const fromUpdateNavigationMenuItemInputToFlatNavigationMenuItemToUpdateOrThrow =
|
||||
({
|
||||
flatNavigationMenuItemMaps,
|
||||
updateNavigationMenuItemInput,
|
||||
}: {
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
updateNavigationMenuItemInput: UpdateNavigationMenuItemInput & {
|
||||
id: string;
|
||||
};
|
||||
}): FlatNavigationMenuItem => {
|
||||
const existingFlatNavigationMenuItem = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: updateNavigationMenuItemInput.id,
|
||||
flatEntityMaps: flatNavigationMenuItemMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(existingFlatNavigationMenuItem)) {
|
||||
throw new NavigationMenuItemException(
|
||||
'Navigation menu item not found',
|
||||
NavigationMenuItemExceptionCode.NAVIGATION_MENU_ITEM_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const { id: _id, ...updates } = updateNavigationMenuItemInput;
|
||||
|
||||
return {
|
||||
...mergeUpdateInExistingRecord({
|
||||
existing: existingFlatNavigationMenuItem,
|
||||
properties: [...FLAT_NAVIGATION_MENU_ITEM_EDITABLE_PROPERTIES],
|
||||
update: updates,
|
||||
}),
|
||||
updatedAt: new Date().toISOString(),
|
||||
};
|
||||
};
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
|
||||
export const removeFlatNavigationMenuItemFromIndex = ({
|
||||
flatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
}: {
|
||||
flatNavigationMenuItem: FlatNavigationMenuItem;
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
}): void => {
|
||||
const userWorkspaceIdKey = flatNavigationMenuItem.userWorkspaceId ?? 'null';
|
||||
const folderIdKey = flatNavigationMenuItem.folderId ?? 'null';
|
||||
|
||||
const itemsArray =
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
userWorkspaceIdKey
|
||||
]?.[folderIdKey];
|
||||
|
||||
if (!itemsArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = itemsArray.findIndex(
|
||||
(item) => item.id === flatNavigationMenuItem.id,
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
itemsArray.splice(index, 1);
|
||||
|
||||
if (itemsArray.length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const userWorkspaceMap =
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[userWorkspaceIdKey];
|
||||
|
||||
if (!userWorkspaceMap) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete userWorkspaceMap[folderIdKey];
|
||||
|
||||
if (Object.keys(userWorkspaceMap).length === 0) {
|
||||
delete flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
userWorkspaceIdKey
|
||||
];
|
||||
}
|
||||
};
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatNavigationMenuItemMaps } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item-maps.type';
|
||||
import { type FlatNavigationMenuItem } from 'src/engine/metadata-modules/flat-navigation-menu-item/types/flat-navigation-menu-item.type';
|
||||
import { removeFlatNavigationMenuItemFromIndex } from 'src/engine/metadata-modules/flat-navigation-menu-item/utils/remove-flat-navigation-menu-item-from-index.util';
|
||||
import { replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow } from 'src/engine/workspace-manager/workspace-migration/utils/replace-flat-entity-in-flat-entity-maps-through-mutation-or-throw.util';
|
||||
|
||||
export const replaceFlatNavigationMenuItemInMapsAndUpdateIndex = ({
|
||||
fromFlatNavigationMenuItem,
|
||||
toFlatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
}: {
|
||||
fromFlatNavigationMenuItem: FlatNavigationMenuItem;
|
||||
toFlatNavigationMenuItem: FlatNavigationMenuItem;
|
||||
flatNavigationMenuItemMaps: FlatNavigationMenuItemMaps;
|
||||
}): void => {
|
||||
const oldUserWorkspaceIdKey =
|
||||
fromFlatNavigationMenuItem.userWorkspaceId ?? 'null';
|
||||
const oldFolderIdKey = fromFlatNavigationMenuItem.folderId ?? 'null';
|
||||
const newUserWorkspaceIdKey =
|
||||
toFlatNavigationMenuItem.userWorkspaceId ?? 'null';
|
||||
const newFolderIdKey = toFlatNavigationMenuItem.folderId ?? 'null';
|
||||
|
||||
const groupChanged =
|
||||
oldUserWorkspaceIdKey !== newUserWorkspaceIdKey ||
|
||||
oldFolderIdKey !== newFolderIdKey;
|
||||
|
||||
if (groupChanged) {
|
||||
removeFlatNavigationMenuItemFromIndex({
|
||||
flatNavigationMenuItem: fromFlatNavigationMenuItem,
|
||||
flatNavigationMenuItemMaps,
|
||||
});
|
||||
}
|
||||
|
||||
replaceFlatEntityInFlatEntityMapsThroughMutationOrThrow({
|
||||
flatEntity: toFlatNavigationMenuItem,
|
||||
flatEntityMapsToMutate: flatNavigationMenuItemMaps,
|
||||
});
|
||||
|
||||
if (groupChanged) {
|
||||
if (
|
||||
!flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
newUserWorkspaceIdKey
|
||||
]
|
||||
) {
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
newUserWorkspaceIdKey
|
||||
] = {};
|
||||
}
|
||||
|
||||
if (
|
||||
!flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
newUserWorkspaceIdKey
|
||||
][newFolderIdKey]
|
||||
) {
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
newUserWorkspaceIdKey
|
||||
][newFolderIdKey] = [];
|
||||
}
|
||||
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
newUserWorkspaceIdKey
|
||||
][newFolderIdKey].push(toFlatNavigationMenuItem);
|
||||
} else {
|
||||
const itemsArray =
|
||||
flatNavigationMenuItemMaps.byUserWorkspaceIdAndFolderId[
|
||||
newUserWorkspaceIdKey
|
||||
]?.[newFolderIdKey];
|
||||
|
||||
if (!itemsArray) {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = itemsArray.findIndex(
|
||||
(item) => item.id === toFlatNavigationMenuItem.id,
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const updatedItem =
|
||||
flatNavigationMenuItemMaps.byId[toFlatNavigationMenuItem.id];
|
||||
|
||||
if (!isDefined(updatedItem)) {
|
||||
return;
|
||||
}
|
||||
|
||||
itemsArray[index] = updatedItem;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user