Unified search algorithm across all lists; per-section record visibility (contacts, deals, activities, leads, finance, tickets, notes, projects)
This commit is contained in:
@@ -25,6 +25,7 @@ import {
|
||||
} from '../common/record-scope';
|
||||
import { normalizeTags } from '../common/tags';
|
||||
import { normalizePersonImportSource } from './person-source';
|
||||
import { buildSearchWhere, ci } from '../common/search';
|
||||
|
||||
function parseDateOrNull(raw?: string | null): Date | null {
|
||||
if (!raw?.trim()) return null;
|
||||
@@ -77,22 +78,22 @@ export class CompaniesService {
|
||||
page = 1,
|
||||
limit = 20,
|
||||
): Promise<PaginatedResponse<CompanyDto>> {
|
||||
const search = buildSearchWhere<Prisma.CompanyWhereInput>(q, (t) => [
|
||||
{ name: ci(t) },
|
||||
{ email: ci(t) },
|
||||
{ phone: { contains: t } },
|
||||
{ otherPhones: { contains: t } },
|
||||
{ nationalId: { contains: t } },
|
||||
{ economicCode: { contains: t } },
|
||||
{ code: ci(t) },
|
||||
{ sourceRef: ci(t) },
|
||||
{ city: ci(t) },
|
||||
{ province: ci(t) },
|
||||
]);
|
||||
const where: Prisma.CompanyWhereInput = {
|
||||
organizationId: actor.organizationId,
|
||||
...ownerWhere(actor),
|
||||
...(q?.trim()
|
||||
? {
|
||||
OR: [
|
||||
{ name: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ email: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ phone: { contains: q.trim() } },
|
||||
{ nationalId: { contains: q.trim() } },
|
||||
{ code: { contains: q.trim() } },
|
||||
{ sourceRef: { contains: q.trim() } },
|
||||
{ city: { contains: q.trim(), mode: 'insensitive' } },
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
...(search ? { AND: [search] } : {}),
|
||||
};
|
||||
|
||||
const [rows, total] = await this.prisma.$transaction([
|
||||
|
||||
@@ -32,6 +32,7 @@ import { AutomationsService } from '../automations/automations.service';
|
||||
import { MessageAutomationsService } from '../message-automations/message-automations.service';
|
||||
import { WebhooksService } from '../public-api/webhooks.service';
|
||||
import { normalizeTags } from '../common/tags';
|
||||
import { buildSearchWhere, ci } from '../common/search';
|
||||
import {
|
||||
normalizePersonImportSource,
|
||||
personImportSourceLabel,
|
||||
@@ -105,27 +106,24 @@ export class PeopleService {
|
||||
const sourceFilter = opts?.importSource?.trim()
|
||||
? normalizePersonImportSource(opts.importSource)
|
||||
: undefined;
|
||||
const search = buildSearchWhere<Prisma.PersonWhereInput>(q, (t) => [
|
||||
{ firstName: ci(t) },
|
||||
{ lastName: ci(t) },
|
||||
{ previousFirstName: ci(t) },
|
||||
{ previousLastName: ci(t) },
|
||||
{ email: ci(t) },
|
||||
{ mobile: { contains: t } },
|
||||
{ phone: { contains: t } },
|
||||
{ sourceRef: ci(t) },
|
||||
{ previousSourceRef: ci(t) },
|
||||
{ company: { name: ci(t) } },
|
||||
]);
|
||||
const where: Prisma.PersonWhereInput = {
|
||||
organizationId: actor.organizationId,
|
||||
...ownerWhere(actor),
|
||||
...(opts?.mood ? { mood: opts.mood } : {}),
|
||||
...(sourceFilter ? { importSource: sourceFilter } : {}),
|
||||
...(q?.trim()
|
||||
? {
|
||||
OR: [
|
||||
{ firstName: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ lastName: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ previousFirstName: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ previousLastName: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ email: { contains: q.trim(), mode: 'insensitive' } },
|
||||
{ mobile: { contains: q.trim() } },
|
||||
{ phone: { contains: q.trim() } },
|
||||
{ sourceRef: { contains: q.trim() } },
|
||||
{ previousSourceRef: { contains: q.trim() } },
|
||||
{ company: { name: { contains: q.trim(), mode: 'insensitive' } } },
|
||||
],
|
||||
}
|
||||
: {}),
|
||||
...(search ? { AND: [search] } : {}),
|
||||
};
|
||||
|
||||
const [rows, total] = await this.prisma.$transaction([
|
||||
|
||||
Reference in New Issue
Block a user