Add row selection, bulk delete, row numbers and page size picker to tables; redesign person profile header

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-05 20:00:21 +03:30
co-authored by Cursor
parent 71b3a7255a
commit 48de552f36
15 changed files with 565 additions and 79 deletions
+10
View File
@@ -1,5 +1,7 @@
import { Type } from 'class-transformer';
import {
ArrayMaxSize,
ArrayMinSize,
IsArray,
IsEmail,
IsIn,
@@ -15,6 +17,14 @@ import {
} from 'class-validator';
import { PERSON_IMPORT_SOURCES, PERSON_MOODS } from '@mento/shared';
export class BulkDeletePeopleDto {
@IsArray()
@ArrayMinSize(1)
@ArrayMaxSize(500)
@IsString({ each: true })
ids!: string[];
}
export class ListQueryDto {
@IsOptional()
@IsString()
+6 -1
View File
@@ -22,7 +22,7 @@ import { CurrentUser } from '../auth/current-user.decorator';
import type { Actor } from '../common/record-scope';
import { OrgModuleGuard } from '../billing/org-module.guard';
import { RequireOrgModule } from '../billing/org-module.decorator';
import { CreatePersonDto, ListQueryDto, UpdatePersonDto } from './dto';
import { BulkDeletePeopleDto, CreatePersonDto, ListQueryDto, UpdatePersonDto } from './dto';
import { PeopleService } from './people.service';
import { ContactsExcelService } from './contacts-excel.service';
import { brand } from '@mento/shared';
@@ -110,6 +110,11 @@ export class PeopleController {
return this.peopleService.get(user, id);
}
@Post('bulk-delete')
bulkDelete(@CurrentUser() user: Actor, @Body() dto: BulkDeletePeopleDto) {
return this.peopleService.removeMany(user, dto.ids);
}
@Post()
create(@CurrentUser() user: Actor, @Body() dto: CreatePersonDto) {
return this.peopleService.create(user, {
+13
View File
@@ -309,6 +309,19 @@ export class PeopleService {
await this.prisma.person.delete({ where: { id } });
}
async removeMany(actor: Actor, ids: string[]): Promise<{ deleted: number }> {
const unique = [...new Set(ids.filter(Boolean))];
if (!unique.length) return { deleted: 0 };
const res = await this.prisma.person.deleteMany({
where: {
id: { in: unique },
organizationId: actor.organizationId,
...ownerWhere(actor),
},
});
return { deleted: res.count };
}
private async ensureExists(actor: Actor, id: string) {
const found = await this.prisma.person.findFirst({
where: { id, organizationId: actor.organizationId, ...ownerWhere(actor) },