fix: move blocks logic

This commit is contained in:
hexastack
2024-11-15 15:53:35 +01:00
parent a864816c34
commit e0a7a783f9
7 changed files with 238 additions and 31 deletions

View File

@@ -255,6 +255,28 @@ export class BlockController extends BaseController<
return await this.blockService.create(block);
}
/**
* Updates multiple blocks by their IDs.
* @param ids - IDs of blocks to be updated.
* @param payload - The data to update blocks with.
* @returns A Promise that resolves to the updates if successful.
*/
@CsrfCheck(true)
@Patch('bulk')
async updateMany(@Body() body: { ids: string[]; payload: BlockUpdateDto }) {
if (!body.ids || body.ids.length === 0) {
throw new BadRequestException('No IDs provided for ...');
}
const updates = await this.blockService.updateMany(
{
_id: { $in: body.ids },
},
body.payload,
);
return updates;
}
/**
* Updates a specific block by ID.
*

View File

@@ -9,7 +9,7 @@
import { Injectable, Optional } from '@nestjs/common';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { InjectModel } from '@nestjs/mongoose';
import {
import mongoose, {
Document,
Model,
Query,
@@ -113,6 +113,88 @@ export class BlockRepository extends BaseRepository<
this.checkDeprecatedAttachmentUrl(updates);
}
/**
* Pre-processing logic for updating blocks.
*
* @param query - The query to update blocks.
* @param criteria - The filter criteria for the update query.
* @param updates - The update data.
*/
async preUpdateMany(
_query: Query<
Document<Block, any, any>,
Document<Block, any, any>,
unknown,
Block,
'updateMany',
Record<string, never>
>,
_criteria: TFilterQuery<Block>,
_updates: UpdateQuery<Document<Block, any, any>>,
): Promise<void> {
const ids: string[] = _criteria._id?.$in || [];
const objIds = ids.map((b) => {
return new mongoose.Types.ObjectId(b);
});
const category: string = _updates.$set.category;
const objCategory = new mongoose.Types.ObjectId(category);
const otherBlocks = await this.model.find({
_id: { $nin: objIds },
category: { $ne: objCategory },
$or: [
{ attachedBlock: { $in: objIds } },
{ nextBlocks: { $in: objIds } },
],
});
for (const id of ids) {
const oldState = await this.model.findOne({
_id: new mongoose.Types.ObjectId(id),
});
if (oldState.category.toString() !== category) {
const updatedNextBlocks = oldState.nextBlocks.filter((nextBlock) =>
ids.includes(nextBlock.toString()),
);
const updatedAttachedBlock = ids.includes(
oldState.attachedBlock?.toString() || '',
)
? oldState.attachedBlock
: null;
await this.model.updateOne(
{ _id: new mongoose.Types.ObjectId(id) },
{
nextBlocks: updatedNextBlocks,
attachedBlock: updatedAttachedBlock,
},
);
}
}
for (const block of otherBlocks) {
if (ids.includes(block.attachedBlock?.toString())) {
await this.model.updateOne(
{ _id: block.id },
{
attachedBlock: null,
},
);
}
if (block.nextBlocks.some((item) => ids.includes(item.toString()))) {
const updatedNextBlocks = block.nextBlocks.filter(
(nextBlock) => !ids.includes(nextBlock.toString()),
);
await this.model.updateOne(
{ _id: block.id },
{
nextBlocks: updatedNextBlocks,
},
);
}
}
}
/**
* Post-processing logic after deleting a block.
*

View File

@@ -38,10 +38,12 @@ export type DeleteResult = {
export enum EHook {
preCreate = 'preCreate',
preUpdate = 'preUpdate',
preUpdateMany = 'preUpdateMany',
preDelete = 'preDelete',
preValidate = 'preValidate',
postCreate = 'postCreate',
postUpdate = 'postUpdate',
postUpdateMany = 'postUpdateMany',
postDelete = 'postDelete',
postValidate = 'postValidate',
}
@@ -157,6 +159,19 @@ export abstract class BaseRepository<
);
});
hooks?.updateMany.pre.execute(async function () {
const query = this as Query<D, D, unknown, T, 'updateMany'>;
const criteria = query.getFilter();
const updates = query.getUpdate();
await repository.preUpdateMany(query, criteria, updates);
repository.emitter.emit(
repository.getEventName(EHook.preUpdateMany),
criteria,
updates?.['$set'],
);
});
hooks?.findOneAndUpdate.post.execute(async function (
updated: HydratedDocument<T>,
) {
@@ -375,6 +390,14 @@ export abstract class BaseRepository<
// Nothing ...
}
async preUpdateMany(
_query: Query<D, D, unknown, T, 'updateMany'>,
_criteria: TFilterQuery<T>,
_updates: UpdateWithAggregationPipeline | UpdateQuery<D>,
) {
// Nothing ...
}
async postUpdate(
_query: Query<D, D, unknown, T, 'findOneAndUpdate'>,
_updated: T,

View File

@@ -17,7 +17,7 @@ enum LifecycleOperation {
// InsertMany = 'insertMany',
// Update = 'update',
// UpdateOne = 'updateOne',
// UpdateMany = 'updateMany',
UpdateMany = 'updateMany',
}
type PreHook = (...args: any[]) => void;
@@ -69,7 +69,7 @@ export class LifecycleHookManager {
// insertMany: ['pre'],
// update: ['pre', 'post'],
// updateOne: ['pre', 'post'],
// updateMany: ['pre', 'post'],
updateMany: ['pre', 'post'],
};
const lifecycleHooks: LifecycleHooks = {} as LifecycleHooks;