@open-mercato/core 0.5.1-develop.3043.1a796c3920 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/AGENTS.md +21 -1
- package/dist/modules/api_keys/api/keys/route.js +9 -0
- package/dist/modules/api_keys/api/keys/route.js.map +2 -2
- package/dist/modules/audit_logs/services/accessLogService.js +13 -0
- package/dist/modules/audit_logs/services/accessLogService.js.map +3 -3
- package/dist/modules/audit_logs/services/actionLogService.js +6 -5
- package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +27 -37
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +41 -28
- package/dist/modules/auth/api/users/route.js.map +3 -3
- package/dist/modules/auth/lib/grantChecks.js +160 -0
- package/dist/modules/auth/lib/grantChecks.js.map +7 -0
- package/dist/modules/configs/cli.js +11 -0
- package/dist/modules/configs/cli.js.map +2 -2
- package/dist/modules/configs/lib/touchGeneratedBarrels.js +46 -0
- package/dist/modules/configs/lib/touchGeneratedBarrels.js.map +7 -0
- package/dist/modules/customers/api/activities/route.js +1 -52
- package/dist/modules/customers/api/activities/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/counts/route.js +2 -1
- package/dist/modules/customers/api/interactions/counts/route.js.map +2 -2
- package/dist/modules/customers/api/interactions/route.js +21 -1
- package/dist/modules/customers/api/interactions/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +7 -3
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +5 -1
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +7 -3
- package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesCard.js +62 -6
- package/dist/modules/customers/components/detail/ActivitiesCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesDayStrip.js +21 -6
- package/dist/modules/customers/components/detail/ActivitiesDayStrip.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivitiesSection.js +37 -5
- package/dist/modules/customers/components/detail/ActivitiesSection.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityCard.js +69 -17
- package/dist/modules/customers/components/detail/ActivityCard.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityHistorySection.js +94 -34
- package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityLogTab.js +3 -1
- package/dist/modules/customers/components/detail/ActivityLogTab.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTimeline.js +41 -8
- package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +19 -6
- package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityTypeSelector.js +4 -3
- package/dist/modules/customers/components/detail/ActivityTypeSelector.js.map +2 -2
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +80 -12
- package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +65 -10
- package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +2 -2
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +10 -5
- package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
- package/dist/modules/customers/data/validators.js +74 -2
- package/dist/modules/customers/data/validators.js.map +2 -2
- package/dist/modules/customers/lib/legacyActivityBridge.js +61 -0
- package/dist/modules/customers/lib/legacyActivityBridge.js.map +7 -0
- package/dist/modules/integrations/data/validators.js +2 -2
- package/dist/modules/integrations/data/validators.js.map +2 -2
- package/dist/modules/integrations/lib/credentials-service.js +12 -1
- package/dist/modules/integrations/lib/credentials-service.js.map +2 -2
- package/dist/modules/messages/commands/actions.js +29 -14
- package/dist/modules/messages/commands/actions.js.map +2 -2
- package/dist/modules/messages/lib/actions.js +24 -4
- package/dist/modules/messages/lib/actions.js.map +2 -2
- package/dist/modules/sales/api/documents/factory.js +49 -36
- package/dist/modules/sales/api/documents/factory.js.map +2 -2
- package/package.json +9 -10
- package/src/modules/api_keys/api/keys/route.ts +9 -0
- package/src/modules/audit_logs/services/accessLogService.ts +20 -0
- package/src/modules/audit_logs/services/actionLogService.ts +13 -5
- package/src/modules/auth/api/roles/acl/route.ts +32 -46
- package/src/modules/auth/api/users/route.ts +48 -33
- package/src/modules/auth/lib/grantChecks.ts +234 -0
- package/src/modules/configs/cli.ts +11 -0
- package/src/modules/configs/lib/touchGeneratedBarrels.ts +61 -0
- package/src/modules/customers/api/activities/route.ts +1 -76
- package/src/modules/customers/api/interactions/counts/route.ts +2 -1
- package/src/modules/customers/api/interactions/route.ts +28 -1
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +13 -3
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +14 -2
- package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +13 -3
- package/src/modules/customers/components/detail/ActivitiesCard.tsx +92 -5
- package/src/modules/customers/components/detail/ActivitiesDayStrip.tsx +38 -6
- package/src/modules/customers/components/detail/ActivitiesSection.tsx +37 -3
- package/src/modules/customers/components/detail/ActivityCard.tsx +79 -14
- package/src/modules/customers/components/detail/ActivityHistorySection.tsx +102 -33
- package/src/modules/customers/components/detail/ActivityLogTab.tsx +7 -1
- package/src/modules/customers/components/detail/ActivityTimeline.tsx +39 -5
- package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +29 -7
- package/src/modules/customers/components/detail/ActivityTypeSelector.tsx +3 -2
- package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +96 -13
- package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +50 -4
- package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +21 -5
- package/src/modules/customers/data/validators.ts +85 -2
- package/src/modules/customers/i18n/de.json +11 -0
- package/src/modules/customers/i18n/en.json +11 -0
- package/src/modules/customers/i18n/es.json +11 -0
- package/src/modules/customers/i18n/pl.json +11 -0
- package/src/modules/customers/lib/legacyActivityBridge.ts +106 -0
- package/src/modules/integrations/data/validators.ts +8 -6
- package/src/modules/integrations/lib/credentials-service.ts +15 -1
- package/src/modules/messages/commands/actions.ts +28 -13
- package/src/modules/messages/lib/actions.ts +34 -3
- package/src/modules/sales/api/documents/factory.ts +55 -38
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/customers/api/interactions/route.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from 'kysely'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { normalizeCustomFieldResponse } from '@open-mercato/shared/lib/custom-fields/normalize'\nimport { applyResponseEnrichers } from '@open-mercato/shared/lib/crud/enricher-runner'\nimport type { EnricherContext } from '@open-mercato/shared/lib/crud/response-enricher'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CustomerDeal, CustomerInteraction } from '../../data/entities'\nimport { User } from '@open-mercato/core/modules/auth/data/entities'\nimport { interactionCreateSchema, interactionUpdateSchema } from '../../data/validators'\nimport { parseScopedCommandInput } from '../utils'\nimport {\n createCustomersCrudOpenApi,\n defaultOkResponseSchema,\n} from '../openapi'\nimport { CUSTOMER_INTERACTION_ENTITY_ID } from '../../lib/interactionCompatibility'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst interactionSortFieldSchema = z.enum([\n 'scheduledAt',\n 'occurredAt',\n 'createdAt',\n 'updatedAt',\n 'status',\n 'priority',\n 'interactionType',\n 'title',\n])\n\nconst listSchema = z\n .object({\n limit: z.coerce.number().min(1).max(100).default(25),\n cursor: z.string().optional(),\n entityId: z.string().uuid().optional(),\n dealId: z.string().uuid().optional(),\n status: z.string().optional(),\n interactionType: z.string().optional(),\n type: z.string().optional(),\n excludeInteractionType: z.string().optional(),\n search: z.string().trim().min(1).optional(),\n from: z.string().optional(),\n to: z.string().optional(),\n pinned: z.enum(['true', 'false']).optional(),\n sortField: interactionSortFieldSchema.optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['customers.interactions.view'] },\n POST: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n}\n\nexport const metadata = routeMetadata\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: CustomerInteraction,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n enrichers: { entityId: 'customers.interaction' },\n indexer: {\n entityType: 'customers:customer_interaction',\n },\n actions: {\n create: {\n commandId: 'customers.interactions.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(interactionCreateSchema, raw ?? {}, ctx, translate)\n },\n response: ({ result }) => ({ id: result?.interactionId ?? result?.id ?? null }),\n status: 201,\n },\n update: {\n commandId: 'customers.interactions.update',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(interactionUpdateSchema, raw ?? {}, ctx, translate)\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'customers.interactions.delete',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n const { translate } = await resolveTranslations()\n const id =\n parsed?.body?.id ??\n parsed?.id ??\n parsed?.query?.id ??\n (ctx.request ? new URL(ctx.request.url).searchParams.get('id') : null)\n if (!id) {\n throw new CrudHttpError(400, {\n error: translate('customers.errors.interaction_required', 'Interaction id is required'),\n })\n }\n return { id }\n },\n response: () => ({ ok: true }),\n },\n },\n})\n\nconst { POST, PUT, DELETE } = crud\n\nexport { POST, PUT, DELETE }\n\ntype InteractionListRow = {\n id: string\n entity_id: string\n deal_id: string | null\n interaction_type: string\n title: string | null\n body: string | null\n status: string\n scheduled_at: Date | null\n occurred_at: Date | null\n priority: number | null\n author_user_id: string | null\n owner_user_id: string | null\n appearance_icon: string | null\n appearance_color: string | null\n source: string | null\n duration_minutes: number | null\n location: string | null\n all_day: boolean | null\n recurrence_rule: string | null\n recurrence_end: Date | null\n participants: Array<{ userId: string; name?: string; email?: string; status?: string }> | null\n reminder_minutes: number | null\n visibility: string | null\n linked_entities: Array<{ id: string; type: string; label: string }> | null\n guest_permissions: { canInviteOthers?: boolean; canModify?: boolean; canSeeList?: boolean } | null\n pinned: boolean\n organization_id: string\n tenant_id: string\n created_at: Date\n updated_at: Date\n __sort_value: string | number | Date | null\n}\n\ntype CursorPayload = {\n id: string\n sortValue: string | number | null\n}\n\ntype RbacServiceLike = {\n getGrantedFeatures?: (userId: string, input: { tenantId: string | null; organizationId: string | null }) => Promise<string[]>\n}\n\nconst cursorSchema = z.object({\n id: z.string().uuid(),\n sortValue: z.union([z.string(), z.number(), z.null()]),\n})\n\nconst interactionSortConfig = {\n scheduledAt: { column: 'scheduled_at', type: 'date' as const, defaultDir: 'asc' as const },\n occurredAt: { column: 'occurred_at', type: 'date' as const, defaultDir: 'desc' as const },\n createdAt: { column: 'created_at', type: 'date' as const, defaultDir: 'desc' as const },\n updatedAt: { column: 'updated_at', type: 'date' as const, defaultDir: 'desc' as const },\n status: { column: 'status', type: 'text' as const, defaultDir: 'asc' as const },\n priority: { column: 'priority', type: 'number' as const, defaultDir: 'desc' as const },\n interactionType: { column: 'interaction_type', type: 'text' as const, defaultDir: 'asc' as const },\n title: { column: 'title', type: 'text' as const, defaultDir: 'asc' as const },\n} as const\n\nfunction toIsoString(value: unknown): string | null {\n if (value == null) return null\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? null : value.toISOString()\n }\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (!trimmed.length) return null\n const parsed = new Date(trimmed)\n return Number.isNaN(parsed.getTime()) ? trimmed : parsed.toISOString()\n }\n return null\n}\n\nfunction normalizeCursorValue(\n value: string | number | Date | null,\n type: 'date' | 'number' | 'text',\n): string | number | null {\n if (value == null) return null\n if (type === 'number') {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? null : parsed\n }\n return null\n }\n if (type === 'date') {\n return toIsoString(value)\n }\n if (typeof value === 'string') return value\n if (value instanceof Date) return value.toISOString()\n return String(value)\n}\n\nfunction encodeCursor(payload: CursorPayload): string {\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64')\n}\n\nfunction decodeCursor(token: string | undefined, type: 'date' | 'number' | 'text'): CursorPayload | null {\n if (!token) return null\n try {\n const decoded = Buffer.from(token, 'base64').toString('utf8')\n const parsed = cursorSchema.parse(JSON.parse(decoded))\n return {\n id: parsed.id,\n sortValue: normalizeCursorValue(parsed.sortValue, type),\n }\n } catch {\n return null\n }\n}\n\nfunction buildSortSql(\n sortField: keyof typeof interactionSortConfig,\n sortDir: 'asc' | 'desc',\n): string {\n const config = interactionSortConfig[sortField]\n if (config.type === 'date') {\n const sentinel =\n sortDir === 'asc'\n ? \"timestamp with time zone '9999-12-31T23:59:59.999Z'\"\n : \"timestamp with time zone '0001-01-01T00:00:00.000Z'\"\n return `coalesce(${config.column}, ${sentinel})`\n }\n if (config.type === 'number') {\n const sentinel = sortDir === 'asc' ? '2147483647' : '-2147483648'\n return `coalesce(${config.column}, ${sentinel})`\n }\n const sentinel = sortDir === 'asc' ? \"'~~~~~~~~~~'\" : \"''\"\n return `coalesce(${config.column}, ${sentinel})`\n}\n\nasync function resolveUserFeatures(\n container: { resolve: (name: string) => unknown },\n userId: string,\n tenantId: string | null,\n organizationId: string | null,\n): Promise<string[] | undefined> {\n try {\n const rbac = container.resolve('rbacService') as RbacServiceLike | undefined\n if (!rbac?.getGrantedFeatures) return undefined\n return await rbac.getGrantedFeatures(userId, { tenantId, organizationId })\n } catch {\n return undefined\n }\n}\n\nasync function buildEnricherContext(\n container: { resolve: (name: string) => unknown },\n auth: NonNullable<Awaited<ReturnType<typeof getAuthFromRequest>>>,\n organizationId: string | null,\n): Promise<EnricherContext> {\n const userId =\n (typeof auth.sub === 'string' && auth.sub.trim().length > 0\n ? auth.sub\n : typeof auth.userId === 'string' && auth.userId.trim().length > 0\n ? auth.userId\n : typeof auth.keyId === 'string' && auth.keyId.trim().length > 0\n ? auth.keyId\n : 'system')\n\n return {\n organizationId: organizationId ?? '',\n tenantId: auth.tenantId ?? '',\n userId,\n em: container.resolve('em'),\n container,\n userFeatures: await resolveUserFeatures(container, userId, auth.tenantId ?? null, organizationId),\n }\n}\n\nexport async function GET(req: Request) {\n try {\n const queryUrl = new URL(req.url)\n const query = listSchema.parse(Object.fromEntries(queryUrl.searchParams))\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, {\n error: translate('customers.errors.unauthorized', 'Unauthorized'),\n })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationIds = Array.isArray(scope?.filterIds) && scope.filterIds.length > 0\n ? scope.filterIds\n : auth.orgId\n ? [auth.orgId]\n : []\n const selectedOrganizationId = scope?.selectedId ?? auth.orgId ?? organizationIds[0] ?? null\n const em = (container.resolve('em') as EntityManager).fork()\n const db = em.getKysely<any>() as any\n\n const requestedSortField = query.sortField ?? 'scheduledAt'\n const sortConfig = interactionSortConfig[requestedSortField]\n const sortDir = query.sortDir ?? sortConfig.defaultDir\n const sortSql = buildSortSql(requestedSortField, sortDir)\n const cursor = decodeCursor(query.cursor, sortConfig.type)\n if (query.cursor && !cursor) {\n throw new CrudHttpError(400, {\n error: translate('customers.interactions.cursor.invalid', 'Invalid cursor'),\n })\n }\n\n let rowsQuery = db\n .selectFrom('customer_interactions')\n .select([\n 'id',\n 'entity_id',\n 'deal_id',\n 'interaction_type',\n 'title',\n 'body',\n 'status',\n 'scheduled_at',\n 'occurred_at',\n 'priority',\n 'author_user_id',\n 'owner_user_id',\n 'appearance_icon',\n 'appearance_color',\n 'source',\n 'duration_minutes',\n 'location',\n 'all_day',\n 'recurrence_rule',\n 'recurrence_end',\n 'participants',\n 'reminder_minutes',\n 'visibility',\n 'linked_entities',\n 'guest_permissions',\n 'pinned',\n 'organization_id',\n 'tenant_id',\n 'created_at',\n 'updated_at',\n sql`${sql.raw(sortSql)}`.as('__sort_value'),\n ])\n .where('deleted_at', 'is', null)\n .where('tenant_id', '=', auth.tenantId)\n .limit(query.limit + 1)\n\n if (organizationIds.length > 0) {\n rowsQuery = rowsQuery.where('organization_id', 'in', organizationIds)\n }\n if (query.entityId) rowsQuery = rowsQuery.where('entity_id', '=', query.entityId)\n if (query.dealId) rowsQuery = rowsQuery.where('deal_id', '=', query.dealId)\n if (query.status) rowsQuery = rowsQuery.where('status', '=', query.status)\n if (query.interactionType) rowsQuery = rowsQuery.where('interaction_type', '=', query.interactionType)\n if (query.type) {\n const types = query.type.split(',').map((t) => t.trim()).filter(Boolean)\n if (types.length > 0) {\n rowsQuery = rowsQuery.where('interaction_type', 'in', types)\n }\n }\n if (query.pinned === 'true') {\n rowsQuery = rowsQuery.where('pinned', '=', true)\n } else if (query.pinned === 'false') {\n rowsQuery = rowsQuery.where('pinned', '=', false)\n }\n if (query.excludeInteractionType) rowsQuery = rowsQuery.where('interaction_type', '!=', query.excludeInteractionType)\n if (query.search) {\n const searchTerm = `%${query.search}%`\n rowsQuery = rowsQuery.where(sql<boolean>`coalesce(title, '') ilike ${searchTerm} or coalesce(body, '') ilike ${searchTerm}`)\n }\n if (query.from) {\n rowsQuery = rowsQuery.where(sql<boolean>`coalesce(occurred_at, scheduled_at, created_at) >= ${new Date(query.from)}`)\n }\n if (query.to) {\n rowsQuery = rowsQuery.where(sql<boolean>`coalesce(occurred_at, scheduled_at, created_at) <= ${new Date(query.to)}`)\n }\n\n if (cursor) {\n const op = sortDir === 'asc' ? '>' : '<'\n const opRaw = sql.raw(op)\n const sortRaw = sql.raw(sortSql)\n rowsQuery = rowsQuery.where((eb: any) => eb.or([\n sql<boolean>`${sortRaw} ${opRaw} ${cursor.sortValue}`,\n eb.and([\n sql<boolean>`${sortRaw} = ${cursor.sortValue}`,\n eb('id', op, cursor.id),\n ]),\n ]))\n }\n\n rowsQuery = rowsQuery.orderBy(sql`${sql.raw(sortSql)} ${sql.raw(sortDir)}`).orderBy('id', sortDir)\n\n const rows = await rowsQuery.execute() as InteractionListRow[]\n const pageRows = rows.slice(0, query.limit)\n const hasMore = rows.length > query.limit\n\n const authorIds = Array.from(\n new Set(\n pageRows\n .map((row) => (typeof row.author_user_id === 'string' ? row.author_user_id : null))\n .filter((value): value is string => !!value),\n ),\n )\n const dealIds = Array.from(\n new Set(\n pageRows\n .map((row) => (typeof row.deal_id === 'string' ? row.deal_id : null))\n .filter((value): value is string => !!value),\n ),\n )\n const interactionIds = pageRows.map((row) => row.id)\n\n const [users, deals, customFieldValues] = await Promise.all([\n authorIds.length > 0 ? findWithDecryption(em, User, { id: { $in: authorIds } }, undefined, { tenantId: auth.tenantId, organizationId: selectedOrganizationId }) : Promise.resolve([]),\n dealIds.length > 0 ? findWithDecryption(em, CustomerDeal, { id: { $in: dealIds } }, undefined, { tenantId: auth.tenantId, organizationId: selectedOrganizationId }) : Promise.resolve([]),\n interactionIds.length > 0\n ? loadCustomFieldValues({\n em,\n entityId: CUSTOMER_INTERACTION_ENTITY_ID,\n recordIds: interactionIds,\n tenantIdByRecord: Object.fromEntries(pageRows.map((row) => [row.id, row.tenant_id])),\n organizationIdByRecord: Object.fromEntries(pageRows.map((row) => [row.id, row.organization_id])),\n tenantFallbacks: [auth.tenantId].filter((value): value is string => !!value),\n })\n : Promise.resolve<Record<string, Record<string, unknown>>>({}),\n ])\n\n const userMap = new Map(\n users.map((user) => [\n user.id,\n {\n name: user.name ?? null,\n email: user.email ?? null,\n },\n ]),\n )\n const dealMap = new Map(\n deals.map((deal) => [deal.id, deal.title]),\n )\n\n const baseItems = pageRows.map((row) => ({\n id: row.id,\n entityId: row.entity_id,\n dealId: row.deal_id ?? null,\n interactionType: row.interaction_type,\n title: row.title ?? null,\n body: row.body ?? null,\n status: row.status,\n scheduledAt: toIsoString(row.scheduled_at),\n occurredAt: toIsoString(row.occurred_at),\n priority: row.priority ?? null,\n authorUserId: row.author_user_id ?? null,\n ownerUserId: row.owner_user_id ?? null,\n appearanceIcon: row.appearance_icon ?? null,\n appearanceColor: row.appearance_color ?? null,\n source: row.source ?? null,\n duration: row.duration_minutes ?? null,\n durationMinutes: row.duration_minutes ?? null,\n location: row.location ?? null,\n allDay: row.all_day ?? null,\n recurrenceRule: row.recurrence_rule ?? null,\n recurrenceEnd: toIsoString(row.recurrence_end),\n participants: row.participants ?? null,\n reminderMinutes: row.reminder_minutes ?? null,\n visibility: row.visibility ?? null,\n linkedEntities: row.linked_entities ?? null,\n guestPermissions: row.guest_permissions ?? null,\n pinned: row.pinned ?? false,\n organizationId: row.organization_id,\n tenantId: row.tenant_id,\n createdAt: toIsoString(row.created_at) ?? new Date().toISOString(),\n updatedAt: toIsoString(row.updated_at) ?? new Date().toISOString(),\n authorName: row.author_user_id ? userMap.get(row.author_user_id)?.name ?? null : null,\n authorEmail: row.author_user_id ? userMap.get(row.author_user_id)?.email ?? null : null,\n dealTitle: row.deal_id ? dealMap.get(row.deal_id) ?? null : null,\n customValues: normalizeCustomFieldResponse(customFieldValues[row.id]) ?? null,\n }))\n\n const enricherContext = await buildEnricherContext(container, auth, selectedOrganizationId)\n const enriched = await applyResponseEnrichers(baseItems, 'customers.interaction', enricherContext)\n\n let nextCursor: string | undefined\n if (hasMore && pageRows.length > 0) {\n const last = pageRows[pageRows.length - 1]\n nextCursor = encodeCursor({\n id: last.id,\n sortValue: normalizeCursorValue(last.__sort_value, sortConfig.type),\n })\n }\n\n return NextResponse.json({\n items: enriched.items,\n nextCursor,\n })\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n if (err instanceof z.ZodError) {\n return NextResponse.json(\n { error: 'Validation failed', details: err.issues },\n { status: 400 },\n )\n }\n console.error('customers.interactions.get failed', err)\n const { translate } = await resolveTranslations()\n return NextResponse.json(\n { error: translate('customers.interactions.load.error', 'Failed to load interactions.') },\n { status: 500 },\n )\n }\n}\n\nconst interactionListItemSchema = z\n .object({\n id: z.string().uuid(),\n entityId: z.string().uuid().nullable(),\n dealId: z.string().uuid().nullable(),\n interactionType: z.string(),\n title: z.string().nullable(),\n body: z.string().nullable(),\n status: z.string(),\n scheduledAt: z.string().nullable(),\n occurredAt: z.string().nullable(),\n priority: z.number().nullable(),\n authorUserId: z.string().uuid().nullable(),\n ownerUserId: z.string().uuid().nullable(),\n appearanceIcon: z.string().nullable().optional(),\n appearanceColor: z.string().nullable().optional(),\n source: z.string().nullable().optional(),\n duration: z.number().nullable().optional(),\n durationMinutes: z.number().nullable().optional(),\n location: z.string().nullable().optional(),\n allDay: z.boolean().nullable().optional(),\n recurrenceRule: z.string().nullable().optional(),\n recurrenceEnd: z.string().nullable().optional(),\n participants: z.array(\n z.object({\n userId: z.string().uuid(),\n name: z.string().optional(),\n email: z.string().optional(),\n status: z.string().optional(),\n }),\n ).nullable().optional(),\n reminderMinutes: z.number().nullable().optional(),\n visibility: z.string().nullable().optional(),\n linkedEntities: z.array(\n z.object({\n id: z.string().uuid(),\n type: z.string(),\n label: z.string(),\n }),\n ).nullable().optional(),\n guestPermissions: z\n .object({\n canInviteOthers: z.boolean().optional(),\n canModify: z.boolean().optional(),\n canSeeList: z.boolean().optional(),\n })\n .nullable()\n .optional(),\n organizationId: z.string().uuid().nullable().optional(),\n tenantId: z.string().uuid().nullable().optional(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n authorName: z.string().nullable().optional(),\n authorEmail: z.string().nullable().optional(),\n dealTitle: z.string().nullable().optional(),\n customValues: z.record(z.string(), z.unknown()).nullable().optional(),\n _integrations: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough()\n\nconst interactionListResponseSchema = z.object({\n items: z.array(interactionListItemSchema),\n nextCursor: z.string().optional(),\n})\n\nconst interactionCreateResponseSchema = z.object({\n id: z.string().uuid().nullable(),\n})\n\nexport const openApi = createCustomersCrudOpenApi({\n resourceName: 'Interaction',\n querySchema: listSchema,\n listResponseSchema: interactionListResponseSchema,\n create: {\n schema: interactionCreateSchema,\n responseSchema: interactionCreateResponseSchema,\n description: 'Creates a new interaction linked to a customer entity or deal.',\n },\n update: {\n schema: interactionUpdateSchema,\n responseSchema: defaultOkResponseSchema,\n description: 'Updates fields for an existing interaction.',\n },\n del: {\n schema: z.object({ id: z.string().uuid() }),\n responseSchema: defaultOkResponseSchema,\n description: 'Soft-deletes an interaction identified by `id`. Accepts id via body or query string.',\n },\n})\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { sql } from 'kysely'\nimport { makeCrudRoute } from '@open-mercato/shared/lib/crud/factory'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { loadCustomFieldValues } from '@open-mercato/shared/lib/crud/custom-fields'\nimport { normalizeCustomFieldResponse } from '@open-mercato/shared/lib/custom-fields/normalize'\nimport { applyResponseEnrichers } from '@open-mercato/shared/lib/crud/enricher-runner'\nimport type { EnricherContext } from '@open-mercato/shared/lib/crud/response-enricher'\nimport { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CustomerDeal, CustomerInteraction } from '../../data/entities'\nimport { User } from '@open-mercato/core/modules/auth/data/entities'\nimport { interactionCreateSchema, interactionUpdateSchema } from '../../data/validators'\nimport { parseScopedCommandInput } from '../utils'\nimport {\n createCustomersCrudOpenApi,\n defaultOkResponseSchema,\n} from '../openapi'\nimport { CUSTOMER_INTERACTION_ENTITY_ID } from '../../lib/interactionCompatibility'\nimport { resolveCanonicalActivityTargetId } from '../../lib/legacyActivityBridge'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\n\nconst rawBodySchema = z.object({}).passthrough()\n\nconst interactionSortFieldSchema = z.enum([\n 'scheduledAt',\n 'occurredAt',\n 'createdAt',\n 'updatedAt',\n 'status',\n 'priority',\n 'interactionType',\n 'title',\n])\n\nconst listSchema = z\n .object({\n limit: z.coerce.number().min(1).max(100).default(25),\n cursor: z.string().optional(),\n entityId: z.string().uuid().optional(),\n dealId: z.string().uuid().optional(),\n status: z.string().optional(),\n interactionType: z.string().optional(),\n type: z.string().optional(),\n excludeInteractionType: z.string().optional(),\n search: z.string().trim().min(1).optional(),\n from: z.string().optional(),\n to: z.string().optional(),\n pinned: z.enum(['true', 'false']).optional(),\n sortField: interactionSortFieldSchema.optional(),\n sortDir: z.enum(['asc', 'desc']).optional(),\n })\n .passthrough()\n\nconst routeMetadata = {\n GET: { requireAuth: true, requireFeatures: ['customers.interactions.view'] },\n POST: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n}\n\nexport const metadata = routeMetadata\n\nconst crud = makeCrudRoute({\n metadata: routeMetadata,\n orm: {\n entity: CustomerInteraction,\n idField: 'id',\n orgField: 'organizationId',\n tenantField: 'tenantId',\n softDeleteField: 'deletedAt',\n },\n enrichers: { entityId: 'customers.interaction' },\n indexer: {\n entityType: 'customers:customer_interaction',\n },\n actions: {\n create: {\n commandId: 'customers.interactions.create',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n return parseScopedCommandInput(interactionCreateSchema, raw ?? {}, ctx, translate)\n },\n response: ({ result }) => ({ id: result?.interactionId ?? result?.id ?? null }),\n status: 201,\n },\n update: {\n commandId: 'customers.interactions.update',\n schema: rawBodySchema,\n mapInput: async ({ raw, ctx }) => {\n const { translate } = await resolveTranslations()\n const parsed = parseScopedCommandInput(interactionUpdateSchema, raw ?? {}, ctx, translate)\n // Bridge legacy `customer_activities` rows into `customer_interactions`\n // before the canonical update runs so historical activities (#1807)\n // remain editable through the new dialog. No-op when the canonical\n // record already exists.\n const tenantId = ctx.auth?.tenantId ?? null\n if (typeof parsed.id === 'string' && tenantId) {\n try {\n const em = ctx.container.resolve('em') as EntityManager\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n const commandContext: CommandRuntimeContext = {\n container: ctx.container,\n auth: ctx.auth ?? null,\n organizationScope: ctx.organizationScope ?? null,\n selectedOrganizationId: ctx.selectedOrganizationId ?? null,\n organizationIds: ctx.organizationIds ?? null,\n request: ctx.request,\n }\n await resolveCanonicalActivityTargetId(em, commandBus, commandContext, parsed.id, tenantId)\n } catch (err) {\n // Bridging is best-effort; downstream lookup will surface a 404\n // when neither canonical nor legacy rows exist.\n console.warn('[customers.interactions.put] legacy bridge failed', { id: parsed.id, error: err })\n }\n }\n return parsed\n },\n response: () => ({ ok: true }),\n },\n delete: {\n commandId: 'customers.interactions.delete',\n schema: rawBodySchema,\n mapInput: async ({ parsed, ctx }) => {\n const { translate } = await resolveTranslations()\n const id =\n parsed?.body?.id ??\n parsed?.id ??\n parsed?.query?.id ??\n (ctx.request ? new URL(ctx.request.url).searchParams.get('id') : null)\n if (!id) {\n throw new CrudHttpError(400, {\n error: translate('customers.errors.interaction_required', 'Interaction id is required'),\n })\n }\n return { id }\n },\n response: () => ({ ok: true }),\n },\n },\n})\n\nconst { POST, PUT, DELETE } = crud\n\nexport { POST, PUT, DELETE }\n\ntype InteractionListRow = {\n id: string\n entity_id: string\n deal_id: string | null\n interaction_type: string\n title: string | null\n body: string | null\n status: string\n scheduled_at: Date | null\n occurred_at: Date | null\n priority: number | null\n author_user_id: string | null\n owner_user_id: string | null\n appearance_icon: string | null\n appearance_color: string | null\n source: string | null\n duration_minutes: number | null\n location: string | null\n all_day: boolean | null\n recurrence_rule: string | null\n recurrence_end: Date | null\n participants: Array<{ userId: string; name?: string; email?: string; status?: string }> | null\n reminder_minutes: number | null\n visibility: string | null\n linked_entities: Array<{ id: string; type: string; label: string }> | null\n guest_permissions: { canInviteOthers?: boolean; canModify?: boolean; canSeeList?: boolean } | null\n pinned: boolean\n organization_id: string\n tenant_id: string\n created_at: Date\n updated_at: Date\n __sort_value: string | number | Date | null\n}\n\ntype CursorPayload = {\n id: string\n sortValue: string | number | null\n}\n\ntype RbacServiceLike = {\n getGrantedFeatures?: (userId: string, input: { tenantId: string | null; organizationId: string | null }) => Promise<string[]>\n}\n\nconst cursorSchema = z.object({\n id: z.string().uuid(),\n sortValue: z.union([z.string(), z.number(), z.null()]),\n})\n\nconst interactionSortConfig = {\n scheduledAt: { column: 'scheduled_at', type: 'date' as const, defaultDir: 'asc' as const },\n occurredAt: { column: 'occurred_at', type: 'date' as const, defaultDir: 'desc' as const },\n createdAt: { column: 'created_at', type: 'date' as const, defaultDir: 'desc' as const },\n updatedAt: { column: 'updated_at', type: 'date' as const, defaultDir: 'desc' as const },\n status: { column: 'status', type: 'text' as const, defaultDir: 'asc' as const },\n priority: { column: 'priority', type: 'number' as const, defaultDir: 'desc' as const },\n interactionType: { column: 'interaction_type', type: 'text' as const, defaultDir: 'asc' as const },\n title: { column: 'title', type: 'text' as const, defaultDir: 'asc' as const },\n} as const\n\nfunction toIsoString(value: unknown): string | null {\n if (value == null) return null\n if (value instanceof Date) {\n return Number.isNaN(value.getTime()) ? null : value.toISOString()\n }\n if (typeof value === 'string') {\n const trimmed = value.trim()\n if (!trimmed.length) return null\n const parsed = new Date(trimmed)\n return Number.isNaN(parsed.getTime()) ? trimmed : parsed.toISOString()\n }\n return null\n}\n\nfunction normalizeCursorValue(\n value: string | number | Date | null,\n type: 'date' | 'number' | 'text',\n): string | number | null {\n if (value == null) return null\n if (type === 'number') {\n if (typeof value === 'number' && Number.isFinite(value)) return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? null : parsed\n }\n return null\n }\n if (type === 'date') {\n return toIsoString(value)\n }\n if (typeof value === 'string') return value\n if (value instanceof Date) return value.toISOString()\n return String(value)\n}\n\nfunction encodeCursor(payload: CursorPayload): string {\n return Buffer.from(JSON.stringify(payload), 'utf8').toString('base64')\n}\n\nfunction decodeCursor(token: string | undefined, type: 'date' | 'number' | 'text'): CursorPayload | null {\n if (!token) return null\n try {\n const decoded = Buffer.from(token, 'base64').toString('utf8')\n const parsed = cursorSchema.parse(JSON.parse(decoded))\n return {\n id: parsed.id,\n sortValue: normalizeCursorValue(parsed.sortValue, type),\n }\n } catch {\n return null\n }\n}\n\nfunction buildSortSql(\n sortField: keyof typeof interactionSortConfig,\n sortDir: 'asc' | 'desc',\n): string {\n const config = interactionSortConfig[sortField]\n if (config.type === 'date') {\n const sentinel =\n sortDir === 'asc'\n ? \"timestamp with time zone '9999-12-31T23:59:59.999Z'\"\n : \"timestamp with time zone '0001-01-01T00:00:00.000Z'\"\n return `coalesce(${config.column}, ${sentinel})`\n }\n if (config.type === 'number') {\n const sentinel = sortDir === 'asc' ? '2147483647' : '-2147483648'\n return `coalesce(${config.column}, ${sentinel})`\n }\n const sentinel = sortDir === 'asc' ? \"'~~~~~~~~~~'\" : \"''\"\n return `coalesce(${config.column}, ${sentinel})`\n}\n\nasync function resolveUserFeatures(\n container: { resolve: (name: string) => unknown },\n userId: string,\n tenantId: string | null,\n organizationId: string | null,\n): Promise<string[] | undefined> {\n try {\n const rbac = container.resolve('rbacService') as RbacServiceLike | undefined\n if (!rbac?.getGrantedFeatures) return undefined\n return await rbac.getGrantedFeatures(userId, { tenantId, organizationId })\n } catch {\n return undefined\n }\n}\n\nasync function buildEnricherContext(\n container: { resolve: (name: string) => unknown },\n auth: NonNullable<Awaited<ReturnType<typeof getAuthFromRequest>>>,\n organizationId: string | null,\n): Promise<EnricherContext> {\n const userId =\n (typeof auth.sub === 'string' && auth.sub.trim().length > 0\n ? auth.sub\n : typeof auth.userId === 'string' && auth.userId.trim().length > 0\n ? auth.userId\n : typeof auth.keyId === 'string' && auth.keyId.trim().length > 0\n ? auth.keyId\n : 'system')\n\n return {\n organizationId: organizationId ?? '',\n tenantId: auth.tenantId ?? '',\n userId,\n em: container.resolve('em'),\n container,\n userFeatures: await resolveUserFeatures(container, userId, auth.tenantId ?? null, organizationId),\n }\n}\n\nexport async function GET(req: Request) {\n try {\n const queryUrl = new URL(req.url)\n const query = listSchema.parse(Object.fromEntries(queryUrl.searchParams))\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, {\n error: translate('customers.errors.unauthorized', 'Unauthorized'),\n })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationIds = Array.isArray(scope?.filterIds) && scope.filterIds.length > 0\n ? scope.filterIds\n : auth.orgId\n ? [auth.orgId]\n : []\n const selectedOrganizationId = scope?.selectedId ?? auth.orgId ?? organizationIds[0] ?? null\n const em = (container.resolve('em') as EntityManager).fork()\n const db = em.getKysely<any>() as any\n\n const requestedSortField = query.sortField ?? 'scheduledAt'\n const sortConfig = interactionSortConfig[requestedSortField]\n const sortDir = query.sortDir ?? sortConfig.defaultDir\n const sortSql = buildSortSql(requestedSortField, sortDir)\n const cursor = decodeCursor(query.cursor, sortConfig.type)\n if (query.cursor && !cursor) {\n throw new CrudHttpError(400, {\n error: translate('customers.interactions.cursor.invalid', 'Invalid cursor'),\n })\n }\n\n let rowsQuery = db\n .selectFrom('customer_interactions')\n .select([\n 'id',\n 'entity_id',\n 'deal_id',\n 'interaction_type',\n 'title',\n 'body',\n 'status',\n 'scheduled_at',\n 'occurred_at',\n 'priority',\n 'author_user_id',\n 'owner_user_id',\n 'appearance_icon',\n 'appearance_color',\n 'source',\n 'duration_minutes',\n 'location',\n 'all_day',\n 'recurrence_rule',\n 'recurrence_end',\n 'participants',\n 'reminder_minutes',\n 'visibility',\n 'linked_entities',\n 'guest_permissions',\n 'pinned',\n 'organization_id',\n 'tenant_id',\n 'created_at',\n 'updated_at',\n sql`${sql.raw(sortSql)}`.as('__sort_value'),\n ])\n .where('deleted_at', 'is', null)\n .where('tenant_id', '=', auth.tenantId)\n .limit(query.limit + 1)\n\n if (organizationIds.length > 0) {\n rowsQuery = rowsQuery.where('organization_id', 'in', organizationIds)\n }\n if (query.entityId) rowsQuery = rowsQuery.where('entity_id', '=', query.entityId)\n if (query.dealId) rowsQuery = rowsQuery.where('deal_id', '=', query.dealId)\n if (query.status) rowsQuery = rowsQuery.where('status', '=', query.status)\n if (query.interactionType) rowsQuery = rowsQuery.where('interaction_type', '=', query.interactionType)\n if (query.type) {\n const types = query.type.split(',').map((t) => t.trim()).filter(Boolean)\n if (types.length > 0) {\n rowsQuery = rowsQuery.where('interaction_type', 'in', types)\n }\n }\n if (query.pinned === 'true') {\n rowsQuery = rowsQuery.where('pinned', '=', true)\n } else if (query.pinned === 'false') {\n rowsQuery = rowsQuery.where('pinned', '=', false)\n }\n if (query.excludeInteractionType) rowsQuery = rowsQuery.where('interaction_type', '!=', query.excludeInteractionType)\n if (query.search) {\n const searchTerm = `%${query.search}%`\n rowsQuery = rowsQuery.where(sql<boolean>`coalesce(title, '') ilike ${searchTerm} or coalesce(body, '') ilike ${searchTerm}`)\n }\n if (query.from) {\n rowsQuery = rowsQuery.where(sql<boolean>`coalesce(occurred_at, scheduled_at, created_at) >= ${new Date(query.from)}`)\n }\n if (query.to) {\n rowsQuery = rowsQuery.where(sql<boolean>`coalesce(occurred_at, scheduled_at, created_at) <= ${new Date(query.to)}`)\n }\n\n if (cursor) {\n const op = sortDir === 'asc' ? '>' : '<'\n const opRaw = sql.raw(op)\n const sortRaw = sql.raw(sortSql)\n rowsQuery = rowsQuery.where((eb: any) => eb.or([\n sql<boolean>`${sortRaw} ${opRaw} ${cursor.sortValue}`,\n eb.and([\n sql<boolean>`${sortRaw} = ${cursor.sortValue}`,\n eb('id', op, cursor.id),\n ]),\n ]))\n }\n\n rowsQuery = rowsQuery.orderBy(sql`${sql.raw(sortSql)} ${sql.raw(sortDir)}`).orderBy('id', sortDir)\n\n const rows = await rowsQuery.execute() as InteractionListRow[]\n const pageRows = rows.slice(0, query.limit)\n const hasMore = rows.length > query.limit\n\n const authorIds = Array.from(\n new Set(\n pageRows\n .map((row) => (typeof row.author_user_id === 'string' ? row.author_user_id : null))\n .filter((value): value is string => !!value),\n ),\n )\n const dealIds = Array.from(\n new Set(\n pageRows\n .map((row) => (typeof row.deal_id === 'string' ? row.deal_id : null))\n .filter((value): value is string => !!value),\n ),\n )\n const interactionIds = pageRows.map((row) => row.id)\n\n const [users, deals, customFieldValues] = await Promise.all([\n authorIds.length > 0 ? findWithDecryption(em, User, { id: { $in: authorIds } }, undefined, { tenantId: auth.tenantId, organizationId: selectedOrganizationId }) : Promise.resolve([]),\n dealIds.length > 0 ? findWithDecryption(em, CustomerDeal, { id: { $in: dealIds } }, undefined, { tenantId: auth.tenantId, organizationId: selectedOrganizationId }) : Promise.resolve([]),\n interactionIds.length > 0\n ? loadCustomFieldValues({\n em,\n entityId: CUSTOMER_INTERACTION_ENTITY_ID,\n recordIds: interactionIds,\n tenantIdByRecord: Object.fromEntries(pageRows.map((row) => [row.id, row.tenant_id])),\n organizationIdByRecord: Object.fromEntries(pageRows.map((row) => [row.id, row.organization_id])),\n tenantFallbacks: [auth.tenantId].filter((value): value is string => !!value),\n })\n : Promise.resolve<Record<string, Record<string, unknown>>>({}),\n ])\n\n const userMap = new Map(\n users.map((user) => [\n user.id,\n {\n name: user.name ?? null,\n email: user.email ?? null,\n },\n ]),\n )\n const dealMap = new Map(\n deals.map((deal) => [deal.id, deal.title]),\n )\n\n const baseItems = pageRows.map((row) => ({\n id: row.id,\n entityId: row.entity_id,\n dealId: row.deal_id ?? null,\n interactionType: row.interaction_type,\n title: row.title ?? null,\n body: row.body ?? null,\n status: row.status,\n scheduledAt: toIsoString(row.scheduled_at),\n occurredAt: toIsoString(row.occurred_at),\n priority: row.priority ?? null,\n authorUserId: row.author_user_id ?? null,\n ownerUserId: row.owner_user_id ?? null,\n appearanceIcon: row.appearance_icon ?? null,\n appearanceColor: row.appearance_color ?? null,\n source: row.source ?? null,\n duration: row.duration_minutes ?? null,\n durationMinutes: row.duration_minutes ?? null,\n location: row.location ?? null,\n allDay: row.all_day ?? null,\n recurrenceRule: row.recurrence_rule ?? null,\n recurrenceEnd: toIsoString(row.recurrence_end),\n participants: row.participants ?? null,\n reminderMinutes: row.reminder_minutes ?? null,\n visibility: row.visibility ?? null,\n linkedEntities: row.linked_entities ?? null,\n guestPermissions: row.guest_permissions ?? null,\n pinned: row.pinned ?? false,\n organizationId: row.organization_id,\n tenantId: row.tenant_id,\n createdAt: toIsoString(row.created_at) ?? new Date().toISOString(),\n updatedAt: toIsoString(row.updated_at) ?? new Date().toISOString(),\n authorName: row.author_user_id ? userMap.get(row.author_user_id)?.name ?? null : null,\n authorEmail: row.author_user_id ? userMap.get(row.author_user_id)?.email ?? null : null,\n dealTitle: row.deal_id ? dealMap.get(row.deal_id) ?? null : null,\n customValues: normalizeCustomFieldResponse(customFieldValues[row.id]) ?? null,\n }))\n\n const enricherContext = await buildEnricherContext(container, auth, selectedOrganizationId)\n const enriched = await applyResponseEnrichers(baseItems, 'customers.interaction', enricherContext)\n\n let nextCursor: string | undefined\n if (hasMore && pageRows.length > 0) {\n const last = pageRows[pageRows.length - 1]\n nextCursor = encodeCursor({\n id: last.id,\n sortValue: normalizeCursorValue(last.__sort_value, sortConfig.type),\n })\n }\n\n return NextResponse.json({\n items: enriched.items,\n nextCursor,\n })\n } catch (err) {\n if (err instanceof CrudHttpError) {\n return NextResponse.json(err.body, { status: err.status })\n }\n if (err instanceof z.ZodError) {\n return NextResponse.json(\n { error: 'Validation failed', details: err.issues },\n { status: 400 },\n )\n }\n console.error('customers.interactions.get failed', err)\n const { translate } = await resolveTranslations()\n return NextResponse.json(\n { error: translate('customers.interactions.load.error', 'Failed to load interactions.') },\n { status: 500 },\n )\n }\n}\n\nconst interactionListItemSchema = z\n .object({\n id: z.string().uuid(),\n entityId: z.string().uuid().nullable(),\n dealId: z.string().uuid().nullable(),\n interactionType: z.string(),\n title: z.string().nullable(),\n body: z.string().nullable(),\n status: z.string(),\n scheduledAt: z.string().nullable(),\n occurredAt: z.string().nullable(),\n priority: z.number().nullable(),\n authorUserId: z.string().uuid().nullable(),\n ownerUserId: z.string().uuid().nullable(),\n appearanceIcon: z.string().nullable().optional(),\n appearanceColor: z.string().nullable().optional(),\n source: z.string().nullable().optional(),\n duration: z.number().nullable().optional(),\n durationMinutes: z.number().nullable().optional(),\n location: z.string().nullable().optional(),\n allDay: z.boolean().nullable().optional(),\n recurrenceRule: z.string().nullable().optional(),\n recurrenceEnd: z.string().nullable().optional(),\n participants: z.array(\n z.object({\n userId: z.string().uuid(),\n name: z.string().optional(),\n email: z.string().optional(),\n status: z.string().optional(),\n }),\n ).nullable().optional(),\n reminderMinutes: z.number().nullable().optional(),\n visibility: z.string().nullable().optional(),\n linkedEntities: z.array(\n z.object({\n id: z.string().uuid(),\n type: z.string(),\n label: z.string(),\n }),\n ).nullable().optional(),\n guestPermissions: z\n .object({\n canInviteOthers: z.boolean().optional(),\n canModify: z.boolean().optional(),\n canSeeList: z.boolean().optional(),\n })\n .nullable()\n .optional(),\n organizationId: z.string().uuid().nullable().optional(),\n tenantId: z.string().uuid().nullable().optional(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n authorName: z.string().nullable().optional(),\n authorEmail: z.string().nullable().optional(),\n dealTitle: z.string().nullable().optional(),\n customValues: z.record(z.string(), z.unknown()).nullable().optional(),\n _integrations: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough()\n\nconst interactionListResponseSchema = z.object({\n items: z.array(interactionListItemSchema),\n nextCursor: z.string().optional(),\n})\n\nconst interactionCreateResponseSchema = z.object({\n id: z.string().uuid().nullable(),\n})\n\nexport const openApi = createCustomersCrudOpenApi({\n resourceName: 'Interaction',\n querySchema: listSchema,\n listResponseSchema: interactionListResponseSchema,\n create: {\n schema: interactionCreateSchema,\n responseSchema: interactionCreateResponseSchema,\n description: 'Creates a new interaction linked to a customer entity or deal.',\n },\n update: {\n schema: interactionUpdateSchema,\n responseSchema: defaultOkResponseSchema,\n description: 'Updates fields for an existing interaction.',\n },\n del: {\n schema: z.object({ id: z.string().uuid() }),\n responseSchema: defaultOkResponseSchema,\n description: 'Soft-deletes an interaction identified by `id`. Accepts id via body or query string.',\n },\n})\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["sentinel"]
|
|
7
7
|
}
|
|
@@ -155,12 +155,13 @@ function CompanyDetailV2Page({ params }) {
|
|
|
155
155
|
const handleEditActivity = React.useCallback((activity) => {
|
|
156
156
|
const raw = activity;
|
|
157
157
|
const durationValue = typeof raw.duration === "number" ? raw.duration : typeof raw.durationMinutes === "number" ? raw.durationMinutes : null;
|
|
158
|
-
|
|
158
|
+
const editPayload = {
|
|
159
159
|
id: activity.id,
|
|
160
160
|
interactionType: typeof activity.interactionType === "string" ? activity.interactionType : void 0,
|
|
161
161
|
title: typeof activity.title === "string" ? activity.title : null,
|
|
162
162
|
body: typeof activity.body === "string" ? activity.body : null,
|
|
163
163
|
scheduledAt: typeof activity.scheduledAt === "string" ? activity.scheduledAt : null,
|
|
164
|
+
occurredAt: typeof activity.occurredAt === "string" ? activity.occurredAt : null,
|
|
164
165
|
durationMinutes: durationValue,
|
|
165
166
|
location: typeof raw.location === "string" ? raw.location : null,
|
|
166
167
|
allDay: typeof raw.allDay === "boolean" ? raw.allDay : null,
|
|
@@ -170,8 +171,11 @@ function CompanyDetailV2Page({ params }) {
|
|
|
170
171
|
reminderMinutes: typeof raw.reminderMinutes === "number" ? raw.reminderMinutes : null,
|
|
171
172
|
visibility: typeof raw.visibility === "string" ? raw.visibility : null,
|
|
172
173
|
linkedEntities: Array.isArray(raw.linkedEntities) ? raw.linkedEntities : null,
|
|
173
|
-
guestPermissions: raw.guestPermissions && typeof raw.guestPermissions === "object" ? raw.guestPermissions : null
|
|
174
|
-
|
|
174
|
+
guestPermissions: raw.guestPermissions && typeof raw.guestPermissions === "object" ? raw.guestPermissions : null,
|
|
175
|
+
customValues: raw.customValues && typeof raw.customValues === "object" ? raw.customValues : null,
|
|
176
|
+
phoneNumber: typeof raw.phoneNumber === "string" ? raw.phoneNumber : null
|
|
177
|
+
};
|
|
178
|
+
setScheduleEditData(editPayload);
|
|
175
179
|
setScheduleDialogOpen(true);
|
|
176
180
|
}, []);
|
|
177
181
|
const openNewScheduleDialog = React.useCallback(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../../src/modules/customers/backend/customers/companies-v2/%5Bid%5D/page.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Building2, Hash, Users, BarChart3, StickyNote } from 'lucide-react'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { AttachmentsSection, ErrorMessage, LoadingMessage, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { InjectionSpot, useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { CollapsibleZoneLayout, type ZoneSectionDescriptor } from '@open-mercato/ui/backend/crud/CollapsibleZoneLayout'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { DealsSection } from '../../../../components/detail/DealsSection'\nimport { ActivityLogTab } from '../../../../components/detail/ActivityLogTab'\nimport { CompanyPeopleSection, type CompanyPersonSummary } from '../../../../components/detail/CompanyPeopleSection'\nimport type { TagSummary } from '../../../../components/detail/types'\nimport type { TagsSectionController } from '@open-mercato/ui/backend/detail'\nimport { coerceDisplayName } from '../../../../lib/displayName'\nimport { CompanyDetailHeader } from '../../../../components/detail/CompanyDetailHeader'\nimport { CompanyDetailTabs, resolveLegacyTab, type CompanyTabId } from '../../../../components/detail/CompanyDetailTabs'\nimport { CompanyKpiBar } from '../../../../components/detail/CompanyKpiBar'\nimport { ScheduleActivityDialog, type ScheduleActivityEditData } from '../../../../components/detail/ScheduleActivityDialog'\nimport { ChangelogTab } from '../../../../components/detail/ChangelogTab'\nimport { useInteractionMutations } from '../../../../components/detail/hooks/useInteractionMutations'\nimport {\n buildCompanyEditPayload,\n createCompanyEditFields,\n createCompanyDaneFiremyGroups,\n createCompanyEditSchema,\n mapCompanyOverviewToFormValues,\n type CompanyEditFormValues,\n type CompanyOverview,\n} from '../../../../components/formConfig'\n\nexport default function CompanyDetailV2Page({ params }: { params?: { id?: string } }) {\n const id = params?.id\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n\n const [data, setData] = React.useState<CompanyOverview | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n\n // Tab state\n const initialTab = React.useMemo(() => {\n return resolveLegacyTab(searchParams?.get('tab'))\n }, [searchParams])\n const [activeTab, setActiveTab] = React.useState<CompanyTabId>(initialTab)\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n\n // Form state\n const [isDirty, setIsDirty] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n const formWrapperRef = React.useRef<HTMLDivElement>(null)\n const { organizationId } = useOrganizationScopeDetail()\n const formSchema = React.useMemo(() => createCompanyEditSchema(), [])\n const formFields = React.useMemo(() => createCompanyEditFields(t), [t])\n const formGroups = React.useMemo(() => createCompanyDaneFiremyGroups(t), [t])\n const initialValues = React.useMemo(\n () => (data ? mapCompanyOverviewToFormValues(data) : undefined),\n [data],\n )\n const zoneSections = React.useMemo<ZoneSectionDescriptor[]>(() => [\n { id: 'identity', icon: Building2, label: t('customers.companies.form.sections.identity', 'Identity') },\n { id: 'contact', icon: Hash, label: t('customers.companies.form.sections.contact', 'Contact') },\n { id: 'classification', icon: Users, label: t('customers.companies.form.sections.classification', 'Classification') },\n { id: 'businessProfile', icon: BarChart3, label: t('customers.companies.form.sections.businessProfile', 'Business profile') },\n { id: 'notes', icon: StickyNote, label: t('customers.companies.form.groups.notes', 'Notes') },\n { id: 'customFields', icon: Hash, label: t('customers.companies.form.groups.customAttributes', 'Custom attributes') },\n ], [t])\n const [scheduleDialogOpen, setScheduleDialogOpen] = React.useState(false)\n const [scheduleEditData, setScheduleEditData] = React.useState<ScheduleActivityEditData | null>(null)\n const [activityRefreshKey, setActivityRefreshKey] = React.useState(0)\n const [dealCount, setDealCount] = React.useState(0)\n\n const currentCompanyId = data?.company?.id ?? null\n const mutationContextId = React.useMemo(\n () => (currentCompanyId ? `customer-company:${currentCompanyId}` : `customer-company:${id ?? 'pending'}`),\n [currentCompanyId, id],\n )\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n companyId?: string | null\n resourceKind: string\n resourceId?: string\n data: CompanyOverview | null\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n const companyDisplayName = coerceDisplayName(data?.company?.displayName)\n const companyName = companyDisplayName.trim().length\n ? companyDisplayName\n : t('customers.companies.list.deleteFallbackName', 'this company')\n\n // Data loading\n const initialLoadDoneRef = React.useRef(false)\n const loadData = React.useCallback(async () => {\n if (!id) {\n setError(t('customers.companies.detail.error.notFound', 'Company not found.'))\n setIsLoading(false)\n return\n }\n if (!initialLoadDoneRef.current) {\n setIsLoading(true)\n }\n setError(null)\n try {\n const payload = await readApiResultOrThrow<CompanyOverview>(\n `/api/customers/companies/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.companies.detail.error.load', 'Failed to load company.') },\n )\n setData(payload as CompanyOverview)\n } catch (err) {\n const message = err instanceof Error ? err.message : t('customers.companies.detail.error.load', 'Failed to load company.')\n setError(message)\n if (!initialLoadDoneRef.current) setData(null)\n } finally {\n setIsLoading(false)\n initialLoadDoneRef.current = true\n }\n }, [id, t])\n\n React.useEffect(() => {\n loadData().catch((err) => console.warn('[companies-v2] loadData failed', err))\n }, [loadData])\n\n React.useEffect(() => {\n setDealCount(data?.counts?.deals ?? 0)\n }, [data?.counts?.deals])\n\n const handleActivityCreated = React.useCallback(() => {\n setActivityRefreshKey((k) => k + 1)\n loadData().catch((err) => console.warn('[companies-v2] reload after activity failed', err))\n }, [loadData])\n\n // Planned activities for the activity-log tab\n const plannedActivities = React.useMemo(() => {\n return data?.plannedActivitiesPreview ?? []\n }, [data?.plannedActivitiesPreview])\n\n // Injection context for UMES\n const injectionContext = React.useMemo(\n () => ({\n formId: mutationContextId,\n companyId: currentCompanyId,\n resourceKind: 'customers.company',\n resourceId: currentCompanyId ?? (id ?? undefined),\n data,\n retryLastMutation,\n }),\n [currentCompanyId, data, id, mutationContextId, retryLastMutation],\n )\n const runMutationWithContext = React.useCallback(\n async <T,>(operation: () => Promise<T>, mutationPayload?: Record<string, unknown>): Promise<T> => {\n return runMutation({\n operation,\n mutationPayload,\n context: injectionContext,\n })\n },\n [injectionContext, runMutation],\n )\n\n const { completeInteraction: handleMarkDone, cancelInteraction: handleCancelActivity } = useInteractionMutations({\n runMutationWithContext,\n onAfterChange: handleActivityCreated,\n logContext: 'customers.companies-v2',\n })\n\n const handleEditActivity = React.useCallback((activity: { id: string; interactionType?: string; title?: string | null; body?: string | null; scheduledAt?: string | null; [key: string]: unknown }) => {\n const raw = activity as Record<string, unknown>\n const durationValue = typeof raw.duration === 'number'\n ? raw.duration\n : typeof raw.durationMinutes === 'number'\n ? raw.durationMinutes as number\n : null\n setScheduleEditData({\n id: activity.id,\n interactionType: typeof activity.interactionType === 'string' ? activity.interactionType : undefined,\n title: typeof activity.title === 'string' ? activity.title : null,\n body: typeof activity.body === 'string' ? activity.body : null,\n scheduledAt: typeof activity.scheduledAt === 'string' ? activity.scheduledAt : null,\n durationMinutes: durationValue,\n location: typeof raw.location === 'string' ? raw.location as string : null,\n allDay: typeof raw.allDay === 'boolean' ? raw.allDay as boolean : null,\n recurrenceRule: typeof raw.recurrenceRule === 'string' ? raw.recurrenceRule as string : null,\n recurrenceEnd: typeof raw.recurrenceEnd === 'string' ? raw.recurrenceEnd as string : null,\n participants: Array.isArray(raw.participants) ? raw.participants as ScheduleActivityEditData['participants'] : null,\n reminderMinutes: typeof raw.reminderMinutes === 'number' ? raw.reminderMinutes as number : null,\n visibility: typeof raw.visibility === 'string' ? raw.visibility as string : null,\n linkedEntities: Array.isArray(raw.linkedEntities) ? raw.linkedEntities as ScheduleActivityEditData['linkedEntities'] : null,\n guestPermissions: raw.guestPermissions && typeof raw.guestPermissions === 'object'\n ? raw.guestPermissions as ScheduleActivityEditData['guestPermissions']\n : null,\n })\n setScheduleDialogOpen(true)\n }, [])\n\n const openNewScheduleDialog = React.useCallback(() => {\n setScheduleEditData(null)\n setScheduleDialogOpen(true)\n }, [])\n\n const handleAddActivity = React.useCallback((kind: 'meeting' | 'call' | 'task' | 'email') => {\n setScheduleEditData({\n id: '',\n interactionType: kind,\n title: null,\n body: null,\n scheduledAt: null,\n durationMinutes: null,\n location: null,\n allDay: null,\n recurrenceRule: null,\n recurrenceEnd: null,\n participants: null,\n reminderMinutes: null,\n visibility: null,\n linkedEntities: null,\n guestPermissions: null,\n })\n setScheduleDialogOpen(true)\n }, [])\n\n // Injected tabs from UMES\n const { widgets: injectedTabWidgets } = useInjectionWidgets('detail:customers.company:tabs', {\n context: injectionContext,\n triggerOnLoad: true,\n })\n\n const injectedTabs = React.useMemo(\n () =>\n (injectedTabWidgets ?? [])\n .filter((widget) => (widget.placement?.kind ?? 'tab') === 'tab')\n .map((widget) => {\n const tabId = widget.placement?.groupId ?? widget.widgetId\n const label = widget.placement?.groupLabel ?? widget.module.metadata.title ?? tabId\n const priority = typeof widget.placement?.priority === 'number' ? widget.placement.priority : 0\n const render = () => (\n <widget.module.Widget\n context={injectionContext}\n data={data}\n onDataChange={(next: unknown) => setData(next as CompanyOverview)}\n />\n )\n return { id: tabId, label, priority, render }\n })\n .sort((a, b) => b.priority - a.priority),\n [data, injectedTabWidgets, injectionContext],\n )\n\n const injectedTabMap = React.useMemo(() => new Map(injectedTabs.map((tab) => [tab.id, tab.render])), [injectedTabs])\n\n // Tags\n const handleTagsChange = React.useCallback((nextTags: TagSummary[]) => {\n setData((prev) => (prev ? { ...prev, tags: nextTags } : prev))\n }, [])\n const tagsSectionControllerRef = React.useRef<TagsSectionController | null>(null)\n\n // Section action (for tabs that expose add/create buttons)\n const handleSectionActionChange = React.useCallback((action: SectionAction | null) => {\n setSectionAction((prev) => (action !== null ? action : prev))\n }, [])\n\n const handleSectionAction = React.useCallback(() => {\n if (!sectionAction || sectionAction.disabled) return\n sectionAction.onClick()\n }, [sectionAction])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n // Deals scope\n const dealsScope = React.useMemo(\n () => (currentCompanyId ? ({ kind: 'company', entityId: currentCompanyId } as const) : null),\n [currentCompanyId],\n )\n\n // Delete handler (shared between header and form)\n const handleDelete = React.useCallback(async () => {\n const companyId = data?.company?.id ?? ''\n if (!companyId) return\n const approved = await confirm({\n title: t('customers.companies.detail.deleteConfirmTitle', 'Delete company?'),\n description: t('customers.companies.detail.deleteConfirmDescription', 'This action cannot be undone.'),\n confirmText: t('customers.companies.detail.actions.delete', 'Delete company'),\n cancelText: t('customers.companies.detail.actions.cancel', 'Cancel'),\n variant: 'destructive',\n })\n if (!approved) return\n await runMutationWithContext(\n () => deleteCrud('customers/companies', { id: companyId }),\n { id: companyId, operation: 'deleteCompany' },\n )\n flash(t('customers.companies.list.deleteSuccess', 'Company deleted.'), 'success')\n router.push('/backend/customers/companies')\n }, [confirm, data?.company?.id, router, runMutationWithContext, t])\n\n // Form submit handler (lifted from CompanyDataTab)\n const handleFormSubmit = React.useCallback(\n async (values: CompanyEditFormValues) => {\n setIsSaving(true)\n try {\n let payload: Record<string, unknown>\n try {\n payload = buildCompanyEditPayload(values, organizationId)\n } catch (err) {\n if (err instanceof Error) {\n if (err.message === 'DISPLAY_NAME_REQUIRED') {\n const message = t('customers.companies.form.displayName.error')\n throw createCrudFormError(message, { displayName: message })\n }\n if (err.message === 'ANNUAL_REVENUE_INVALID') {\n const message = t('customers.companies.form.annualRevenue.error')\n throw createCrudFormError(message, { annualRevenue: message })\n }\n }\n throw err\n }\n await updateCrud('customers/companies', payload)\n flash(t('customers.companies.form.updateSuccess', 'Company updated.'), 'success')\n await loadData()\n } finally {\n setIsSaving(false)\n }\n },\n [loadData, organizationId, t],\n )\n\n // Save handler (triggers form submit via ref)\n const handleHeaderSave = React.useCallback(() => {\n const form = formWrapperRef.current?.querySelector('form')\n if (form) form.requestSubmit()\n }, [])\n\n // Loading / error states\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <LoadingMessage label={t('customers.companies.detail.loading', 'Loading company\u2026')} />\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data?.company?.id) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={error || t('customers.companies.detail.error.notFound', 'Company not found.')}\n action={(\n <Button asChild variant=\"outline\">\n <Link href=\"/backend/customers/companies\">\n {t('customers.companies.detail.actions.backToList', 'Back to companies')}\n </Link>\n </Button>\n )}\n />\n </PageBody>\n </Page>\n )\n }\n\n const companyId = data.company.id\n const useCanonicalInteractions = data.interactionMode === 'canonical'\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n {/* UMES header injection */}\n <InjectionSpot spotId=\"detail:customers.company:header\" context={injectionContext} data={data} />\n <InjectionSpot spotId=\"detail:customers.company:status-badges\" context={injectionContext} data={data} />\n\n {/* Persistent company header */}\n <CompanyDetailHeader\n data={data}\n onTagsChange={handleTagsChange}\n tagsSectionControllerRef={tagsSectionControllerRef}\n onSave={handleHeaderSave}\n onDelete={handleDelete}\n isDirty={isDirty}\n isSaving={isSaving}\n onDataReload={() => { loadData().catch((err) => console.warn('[companies-v2] onDataReload failed', err)) }}\n />\n\n {/* KPI bar \u2014 always visible above zones */}\n <CompanyKpiBar data={data} />\n\n {/* Two-zone layout: zone1 = form, zone2 = tabs */}\n <CollapsibleZoneLayout\n pageType=\"company-v2\"\n entityName={companyName}\n isDirty={isDirty}\n sections={zoneSections}\n zone1={\n <div ref={formWrapperRef}>\n <CrudForm<CompanyEditFormValues>\n embedded\n trackDirtyWhenEmbedded\n injectionSpotId=\"customers.company\"\n entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}\n schema={formSchema}\n fields={formFields}\n groups={formGroups}\n initialValues={initialValues}\n onSubmit={handleFormSubmit}\n onDelete={handleDelete}\n hideFooterActions\n collapsibleGroups={{ pageType: 'company-v2', chevronPosition: 'left' }}\n sortableGroups={{ pageType: 'company-v2' }}\n onDirtyChange={setIsDirty}\n />\n </div>\n }\n zone2={\n <CompanyDetailTabs\n activeTab={activeTab}\n onTabChange={setActiveTab}\n injectedTabs={injectedTabs.map((tab) => ({ id: tab.id, label: tab.label }))}\n peopleCount={data.counts?.people ?? 0}\n dealsCount={dealCount}\n activitiesCount={data.counts?.activities ?? 0}\n sectionAction={sectionAction}\n >\n {activeTab === 'people' && (\n <CompanyPeopleSection\n companyId={companyId}\n companyName={companyDisplayName}\n initialPeople={[]}\n addActionLabel={t('customers.companies.detail.people.add', 'Add person')}\n emptyLabel={t('customers.companies.detail.people.empty', 'No people linked to this company yet.')}\n emptyState={{\n title: t('customers.companies.detail.emptyState.people.title', 'Build the account team'),\n actionLabel: t('customers.companies.detail.emptyState.people.action', 'Create person'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n runGuardedMutation={runMutationWithContext}\n onPeopleChange={(next) => {\n setData((prev) => {\n if (!prev) return prev\n const nextCount = next.length\n return {\n ...prev,\n people: next,\n counts: prev.counts ? { ...prev.counts, people: nextCount } : prev.counts,\n }\n })\n }}\n />\n )}\n\n {activeTab === 'deals' && (\n <DealsSection\n scope={dealsScope}\n emptyLabel={t('customers.companies.detail.empty.deals', 'No deals linked to this company.')}\n addActionLabel={t('customers.companies.detail.actions.addDeal', 'Add deal')}\n emptyState={{\n title: t('customers.companies.detail.emptyState.deals.title', 'No deals yet'),\n actionLabel: t('customers.companies.detail.emptyState.deals.action', 'Create a deal'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n runGuardedMutation={runMutationWithContext}\n onCountDelta={(delta) => setDealCount((current) => Math.max(0, current + delta))}\n />\n )}\n\n {activeTab === 'activity-log' && (\n <ActivityLogTab\n entityId={companyId}\n plannedActivities={plannedActivities}\n onActivityCreated={handleActivityCreated}\n onScheduleRequested={openNewScheduleDialog}\n onAddActivity={handleAddActivity}\n onMarkDone={handleMarkDone}\n onEditActivity={handleEditActivity}\n onCancelActivity={handleCancelActivity}\n runGuardedMutation={runMutationWithContext}\n refreshKey={activityRefreshKey}\n useCanonicalInteractions={useCanonicalInteractions}\n />\n )}\n\n {activeTab === 'changelog' && companyId && (\n <ChangelogTab entityId={companyId} entityType=\"company\" />\n )}\n\n {activeTab === 'files' && (\n <AttachmentsSection\n entityId={E.customers.customer_entity}\n recordId={companyId}\n title={t('customers.companies.detail.tabs.files', 'Files')}\n description={t('customers.companies.detail.files.subtitle', 'Upload and manage files linked to this company.')}\n />\n )}\n\n {/* Injected tabs from UMES */}\n {injectedTabMap.has(activeTab) && injectedTabMap.get(activeTab)!()}\n </CompanyDetailTabs>\n }\n />\n\n {/* UMES footer injection */}\n <InjectionSpot spotId=\"detail:customers.company:footer\" context={injectionContext} data={data} />\n\n {/* Schedule Activity Dialog */}\n <ScheduleActivityDialog\n open={scheduleDialogOpen}\n onClose={() => { setScheduleDialogOpen(false); setScheduleEditData(null) }}\n entityId={companyId}\n entityName={companyName}\n entityType=\"company\"\n onActivityCreated={handleActivityCreated}\n editData={scheduleEditData}\n />\n {ConfirmDialogElement}\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Building2, Hash, Users, BarChart3, StickyNote } from 'lucide-react'\nimport { updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { apiCallOrThrow, readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { AttachmentsSection, ErrorMessage, LoadingMessage, type SectionAction } from '@open-mercato/ui/backend/detail'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { InjectionSpot, useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { createTranslatorWithFallback } from '@open-mercato/shared/lib/i18n/translate'\nimport { CrudForm } from '@open-mercato/ui/backend/CrudForm'\nimport { CollapsibleZoneLayout, type ZoneSectionDescriptor } from '@open-mercato/ui/backend/crud/CollapsibleZoneLayout'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { E } from '#generated/entities.ids.generated'\nimport { useOrganizationScopeDetail } from '@open-mercato/shared/lib/frontend/useOrganizationScope'\nimport { DealsSection } from '../../../../components/detail/DealsSection'\nimport { ActivityLogTab } from '../../../../components/detail/ActivityLogTab'\nimport { CompanyPeopleSection, type CompanyPersonSummary } from '../../../../components/detail/CompanyPeopleSection'\nimport type { TagSummary } from '../../../../components/detail/types'\nimport type { TagsSectionController } from '@open-mercato/ui/backend/detail'\nimport { coerceDisplayName } from '../../../../lib/displayName'\nimport { CompanyDetailHeader } from '../../../../components/detail/CompanyDetailHeader'\nimport { CompanyDetailTabs, resolveLegacyTab, type CompanyTabId } from '../../../../components/detail/CompanyDetailTabs'\nimport { CompanyKpiBar } from '../../../../components/detail/CompanyKpiBar'\nimport { ScheduleActivityDialog, type ScheduleActivityEditData } from '../../../../components/detail/ScheduleActivityDialog'\nimport { ChangelogTab } from '../../../../components/detail/ChangelogTab'\nimport { useInteractionMutations } from '../../../../components/detail/hooks/useInteractionMutations'\nimport {\n buildCompanyEditPayload,\n createCompanyEditFields,\n createCompanyDaneFiremyGroups,\n createCompanyEditSchema,\n mapCompanyOverviewToFormValues,\n type CompanyEditFormValues,\n type CompanyOverview,\n} from '../../../../components/formConfig'\n\nexport default function CompanyDetailV2Page({ params }: { params?: { id?: string } }) {\n const id = params?.id\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const detailTranslator = React.useMemo(() => createTranslatorWithFallback(t), [t])\n\n const [data, setData] = React.useState<CompanyOverview | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n\n // Tab state\n const initialTab = React.useMemo(() => {\n return resolveLegacyTab(searchParams?.get('tab'))\n }, [searchParams])\n const [activeTab, setActiveTab] = React.useState<CompanyTabId>(initialTab)\n const [sectionAction, setSectionAction] = React.useState<SectionAction | null>(null)\n\n // Form state\n const [isDirty, setIsDirty] = React.useState(false)\n const [isSaving, setIsSaving] = React.useState(false)\n const formWrapperRef = React.useRef<HTMLDivElement>(null)\n const { organizationId } = useOrganizationScopeDetail()\n const formSchema = React.useMemo(() => createCompanyEditSchema(), [])\n const formFields = React.useMemo(() => createCompanyEditFields(t), [t])\n const formGroups = React.useMemo(() => createCompanyDaneFiremyGroups(t), [t])\n const initialValues = React.useMemo(\n () => (data ? mapCompanyOverviewToFormValues(data) : undefined),\n [data],\n )\n const zoneSections = React.useMemo<ZoneSectionDescriptor[]>(() => [\n { id: 'identity', icon: Building2, label: t('customers.companies.form.sections.identity', 'Identity') },\n { id: 'contact', icon: Hash, label: t('customers.companies.form.sections.contact', 'Contact') },\n { id: 'classification', icon: Users, label: t('customers.companies.form.sections.classification', 'Classification') },\n { id: 'businessProfile', icon: BarChart3, label: t('customers.companies.form.sections.businessProfile', 'Business profile') },\n { id: 'notes', icon: StickyNote, label: t('customers.companies.form.groups.notes', 'Notes') },\n { id: 'customFields', icon: Hash, label: t('customers.companies.form.groups.customAttributes', 'Custom attributes') },\n ], [t])\n const [scheduleDialogOpen, setScheduleDialogOpen] = React.useState(false)\n const [scheduleEditData, setScheduleEditData] = React.useState<ScheduleActivityEditData | null>(null)\n const [activityRefreshKey, setActivityRefreshKey] = React.useState(0)\n const [dealCount, setDealCount] = React.useState(0)\n\n const currentCompanyId = data?.company?.id ?? null\n const mutationContextId = React.useMemo(\n () => (currentCompanyId ? `customer-company:${currentCompanyId}` : `customer-company:${id ?? 'pending'}`),\n [currentCompanyId, id],\n )\n const { runMutation, retryLastMutation } = useGuardedMutation<{\n formId: string\n companyId?: string | null\n resourceKind: string\n resourceId?: string\n data: CompanyOverview | null\n retryLastMutation: () => Promise<boolean>\n }>({\n contextId: mutationContextId,\n blockedMessage: t('ui.forms.flash.saveBlocked', 'Save blocked by validation'),\n })\n\n const companyDisplayName = coerceDisplayName(data?.company?.displayName)\n const companyName = companyDisplayName.trim().length\n ? companyDisplayName\n : t('customers.companies.list.deleteFallbackName', 'this company')\n\n // Data loading\n const initialLoadDoneRef = React.useRef(false)\n const loadData = React.useCallback(async () => {\n if (!id) {\n setError(t('customers.companies.detail.error.notFound', 'Company not found.'))\n setIsLoading(false)\n return\n }\n if (!initialLoadDoneRef.current) {\n setIsLoading(true)\n }\n setError(null)\n try {\n const payload = await readApiResultOrThrow<CompanyOverview>(\n `/api/customers/companies/${encodeURIComponent(id)}`,\n undefined,\n { errorMessage: t('customers.companies.detail.error.load', 'Failed to load company.') },\n )\n setData(payload as CompanyOverview)\n } catch (err) {\n const message = err instanceof Error ? err.message : t('customers.companies.detail.error.load', 'Failed to load company.')\n setError(message)\n if (!initialLoadDoneRef.current) setData(null)\n } finally {\n setIsLoading(false)\n initialLoadDoneRef.current = true\n }\n }, [id, t])\n\n React.useEffect(() => {\n loadData().catch((err) => console.warn('[companies-v2] loadData failed', err))\n }, [loadData])\n\n React.useEffect(() => {\n setDealCount(data?.counts?.deals ?? 0)\n }, [data?.counts?.deals])\n\n const handleActivityCreated = React.useCallback(() => {\n setActivityRefreshKey((k) => k + 1)\n loadData().catch((err) => console.warn('[companies-v2] reload after activity failed', err))\n }, [loadData])\n\n // Planned activities for the activity-log tab\n const plannedActivities = React.useMemo(() => {\n return data?.plannedActivitiesPreview ?? []\n }, [data?.plannedActivitiesPreview])\n\n // Injection context for UMES\n const injectionContext = React.useMemo(\n () => ({\n formId: mutationContextId,\n companyId: currentCompanyId,\n resourceKind: 'customers.company',\n resourceId: currentCompanyId ?? (id ?? undefined),\n data,\n retryLastMutation,\n }),\n [currentCompanyId, data, id, mutationContextId, retryLastMutation],\n )\n const runMutationWithContext = React.useCallback(\n async <T,>(operation: () => Promise<T>, mutationPayload?: Record<string, unknown>): Promise<T> => {\n return runMutation({\n operation,\n mutationPayload,\n context: injectionContext,\n })\n },\n [injectionContext, runMutation],\n )\n\n const { completeInteraction: handleMarkDone, cancelInteraction: handleCancelActivity } = useInteractionMutations({\n runMutationWithContext,\n onAfterChange: handleActivityCreated,\n logContext: 'customers.companies-v2',\n })\n\n const handleEditActivity = React.useCallback((activity: { id: string; interactionType?: string; title?: string | null; body?: string | null; scheduledAt?: string | null; occurredAt?: string | null; [key: string]: unknown }) => {\n const raw = activity as Record<string, unknown>\n const durationValue = typeof raw.duration === 'number'\n ? raw.duration\n : typeof raw.durationMinutes === 'number'\n ? raw.durationMinutes as number\n : null\n // Forward `customValues` so per-type chip state (callPhoneNumber, callDirection,\n // taskPriority, \u2026) round-trips on edit (#1808 phone persistence).\n // Forward `occurredAt` so historical activity edits prefill from the original\n // moment instead of \"today\" (#1807 prefill).\n const editPayload = {\n id: activity.id,\n interactionType: typeof activity.interactionType === 'string' ? activity.interactionType : undefined,\n title: typeof activity.title === 'string' ? activity.title : null,\n body: typeof activity.body === 'string' ? activity.body : null,\n scheduledAt: typeof activity.scheduledAt === 'string' ? activity.scheduledAt : null,\n occurredAt: typeof activity.occurredAt === 'string' ? activity.occurredAt : null,\n durationMinutes: durationValue,\n location: typeof raw.location === 'string' ? raw.location as string : null,\n allDay: typeof raw.allDay === 'boolean' ? raw.allDay as boolean : null,\n recurrenceRule: typeof raw.recurrenceRule === 'string' ? raw.recurrenceRule as string : null,\n recurrenceEnd: typeof raw.recurrenceEnd === 'string' ? raw.recurrenceEnd as string : null,\n participants: Array.isArray(raw.participants) ? raw.participants as ScheduleActivityEditData['participants'] : null,\n reminderMinutes: typeof raw.reminderMinutes === 'number' ? raw.reminderMinutes as number : null,\n visibility: typeof raw.visibility === 'string' ? raw.visibility as string : null,\n linkedEntities: Array.isArray(raw.linkedEntities) ? raw.linkedEntities as ScheduleActivityEditData['linkedEntities'] : null,\n guestPermissions: raw.guestPermissions && typeof raw.guestPermissions === 'object'\n ? raw.guestPermissions as ScheduleActivityEditData['guestPermissions']\n : null,\n customValues: raw.customValues && typeof raw.customValues === 'object'\n ? raw.customValues as Record<string, unknown>\n : null,\n phoneNumber: typeof raw.phoneNumber === 'string' ? raw.phoneNumber as string : null,\n } as ScheduleActivityEditData & { customValues?: Record<string, unknown> | null; phoneNumber?: string | null }\n setScheduleEditData(editPayload)\n setScheduleDialogOpen(true)\n }, [])\n\n const openNewScheduleDialog = React.useCallback(() => {\n setScheduleEditData(null)\n setScheduleDialogOpen(true)\n }, [])\n\n const handleAddActivity = React.useCallback((kind: 'meeting' | 'call' | 'task' | 'email') => {\n setScheduleEditData({\n id: '',\n interactionType: kind,\n title: null,\n body: null,\n scheduledAt: null,\n durationMinutes: null,\n location: null,\n allDay: null,\n recurrenceRule: null,\n recurrenceEnd: null,\n participants: null,\n reminderMinutes: null,\n visibility: null,\n linkedEntities: null,\n guestPermissions: null,\n })\n setScheduleDialogOpen(true)\n }, [])\n\n // Injected tabs from UMES\n const { widgets: injectedTabWidgets } = useInjectionWidgets('detail:customers.company:tabs', {\n context: injectionContext,\n triggerOnLoad: true,\n })\n\n const injectedTabs = React.useMemo(\n () =>\n (injectedTabWidgets ?? [])\n .filter((widget) => (widget.placement?.kind ?? 'tab') === 'tab')\n .map((widget) => {\n const tabId = widget.placement?.groupId ?? widget.widgetId\n const label = widget.placement?.groupLabel ?? widget.module.metadata.title ?? tabId\n const priority = typeof widget.placement?.priority === 'number' ? widget.placement.priority : 0\n const render = () => (\n <widget.module.Widget\n context={injectionContext}\n data={data}\n onDataChange={(next: unknown) => setData(next as CompanyOverview)}\n />\n )\n return { id: tabId, label, priority, render }\n })\n .sort((a, b) => b.priority - a.priority),\n [data, injectedTabWidgets, injectionContext],\n )\n\n const injectedTabMap = React.useMemo(() => new Map(injectedTabs.map((tab) => [tab.id, tab.render])), [injectedTabs])\n\n // Tags\n const handleTagsChange = React.useCallback((nextTags: TagSummary[]) => {\n setData((prev) => (prev ? { ...prev, tags: nextTags } : prev))\n }, [])\n const tagsSectionControllerRef = React.useRef<TagsSectionController | null>(null)\n\n // Section action (for tabs that expose add/create buttons)\n const handleSectionActionChange = React.useCallback((action: SectionAction | null) => {\n setSectionAction((prev) => (action !== null ? action : prev))\n }, [])\n\n const handleSectionAction = React.useCallback(() => {\n if (!sectionAction || sectionAction.disabled) return\n sectionAction.onClick()\n }, [sectionAction])\n\n React.useEffect(() => {\n setSectionAction(null)\n }, [activeTab])\n\n // Deals scope\n const dealsScope = React.useMemo(\n () => (currentCompanyId ? ({ kind: 'company', entityId: currentCompanyId } as const) : null),\n [currentCompanyId],\n )\n\n // Delete handler (shared between header and form)\n const handleDelete = React.useCallback(async () => {\n const companyId = data?.company?.id ?? ''\n if (!companyId) return\n const approved = await confirm({\n title: t('customers.companies.detail.deleteConfirmTitle', 'Delete company?'),\n description: t('customers.companies.detail.deleteConfirmDescription', 'This action cannot be undone.'),\n confirmText: t('customers.companies.detail.actions.delete', 'Delete company'),\n cancelText: t('customers.companies.detail.actions.cancel', 'Cancel'),\n variant: 'destructive',\n })\n if (!approved) return\n await runMutationWithContext(\n () => deleteCrud('customers/companies', { id: companyId }),\n { id: companyId, operation: 'deleteCompany' },\n )\n flash(t('customers.companies.list.deleteSuccess', 'Company deleted.'), 'success')\n router.push('/backend/customers/companies')\n }, [confirm, data?.company?.id, router, runMutationWithContext, t])\n\n // Form submit handler (lifted from CompanyDataTab)\n const handleFormSubmit = React.useCallback(\n async (values: CompanyEditFormValues) => {\n setIsSaving(true)\n try {\n let payload: Record<string, unknown>\n try {\n payload = buildCompanyEditPayload(values, organizationId)\n } catch (err) {\n if (err instanceof Error) {\n if (err.message === 'DISPLAY_NAME_REQUIRED') {\n const message = t('customers.companies.form.displayName.error')\n throw createCrudFormError(message, { displayName: message })\n }\n if (err.message === 'ANNUAL_REVENUE_INVALID') {\n const message = t('customers.companies.form.annualRevenue.error')\n throw createCrudFormError(message, { annualRevenue: message })\n }\n }\n throw err\n }\n await updateCrud('customers/companies', payload)\n flash(t('customers.companies.form.updateSuccess', 'Company updated.'), 'success')\n await loadData()\n } finally {\n setIsSaving(false)\n }\n },\n [loadData, organizationId, t],\n )\n\n // Save handler (triggers form submit via ref)\n const handleHeaderSave = React.useCallback(() => {\n const form = formWrapperRef.current?.querySelector('form')\n if (form) form.requestSubmit()\n }, [])\n\n // Loading / error states\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <LoadingMessage label={t('customers.companies.detail.loading', 'Loading company\u2026')} />\n </PageBody>\n </Page>\n )\n }\n\n if (error || !data?.company?.id) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={error || t('customers.companies.detail.error.notFound', 'Company not found.')}\n action={(\n <Button asChild variant=\"outline\">\n <Link href=\"/backend/customers/companies\">\n {t('customers.companies.detail.actions.backToList', 'Back to companies')}\n </Link>\n </Button>\n )}\n />\n </PageBody>\n </Page>\n )\n }\n\n const companyId = data.company.id\n const useCanonicalInteractions = data.interactionMode === 'canonical'\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n {/* UMES header injection */}\n <InjectionSpot spotId=\"detail:customers.company:header\" context={injectionContext} data={data} />\n <InjectionSpot spotId=\"detail:customers.company:status-badges\" context={injectionContext} data={data} />\n\n {/* Persistent company header */}\n <CompanyDetailHeader\n data={data}\n onTagsChange={handleTagsChange}\n tagsSectionControllerRef={tagsSectionControllerRef}\n onSave={handleHeaderSave}\n onDelete={handleDelete}\n isDirty={isDirty}\n isSaving={isSaving}\n onDataReload={() => { loadData().catch((err) => console.warn('[companies-v2] onDataReload failed', err)) }}\n />\n\n {/* KPI bar \u2014 always visible above zones */}\n <CompanyKpiBar data={data} />\n\n {/* Two-zone layout: zone1 = form, zone2 = tabs */}\n <CollapsibleZoneLayout\n pageType=\"company-v2\"\n entityName={companyName}\n isDirty={isDirty}\n sections={zoneSections}\n zone1={\n <div ref={formWrapperRef}>\n <CrudForm<CompanyEditFormValues>\n embedded\n trackDirtyWhenEmbedded\n injectionSpotId=\"customers.company\"\n entityIds={[E.customers.customer_entity, E.customers.customer_company_profile]}\n schema={formSchema}\n fields={formFields}\n groups={formGroups}\n initialValues={initialValues}\n onSubmit={handleFormSubmit}\n onDelete={handleDelete}\n hideFooterActions\n collapsibleGroups={{ pageType: 'company-v2', chevronPosition: 'left' }}\n sortableGroups={{ pageType: 'company-v2' }}\n onDirtyChange={setIsDirty}\n />\n </div>\n }\n zone2={\n <CompanyDetailTabs\n activeTab={activeTab}\n onTabChange={setActiveTab}\n injectedTabs={injectedTabs.map((tab) => ({ id: tab.id, label: tab.label }))}\n peopleCount={data.counts?.people ?? 0}\n dealsCount={dealCount}\n activitiesCount={data.counts?.activities ?? 0}\n sectionAction={sectionAction}\n >\n {activeTab === 'people' && (\n <CompanyPeopleSection\n companyId={companyId}\n companyName={companyDisplayName}\n initialPeople={[]}\n addActionLabel={t('customers.companies.detail.people.add', 'Add person')}\n emptyLabel={t('customers.companies.detail.people.empty', 'No people linked to this company yet.')}\n emptyState={{\n title: t('customers.companies.detail.emptyState.people.title', 'Build the account team'),\n actionLabel: t('customers.companies.detail.emptyState.people.action', 'Create person'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n runGuardedMutation={runMutationWithContext}\n onPeopleChange={(next) => {\n setData((prev) => {\n if (!prev) return prev\n const nextCount = next.length\n return {\n ...prev,\n people: next,\n counts: prev.counts ? { ...prev.counts, people: nextCount } : prev.counts,\n }\n })\n }}\n />\n )}\n\n {activeTab === 'deals' && (\n <DealsSection\n scope={dealsScope}\n emptyLabel={t('customers.companies.detail.empty.deals', 'No deals linked to this company.')}\n addActionLabel={t('customers.companies.detail.actions.addDeal', 'Add deal')}\n emptyState={{\n title: t('customers.companies.detail.emptyState.deals.title', 'No deals yet'),\n actionLabel: t('customers.companies.detail.emptyState.deals.action', 'Create a deal'),\n }}\n onActionChange={handleSectionActionChange}\n translator={detailTranslator}\n runGuardedMutation={runMutationWithContext}\n onCountDelta={(delta) => setDealCount((current) => Math.max(0, current + delta))}\n />\n )}\n\n {activeTab === 'activity-log' && (\n <ActivityLogTab\n entityId={companyId}\n plannedActivities={plannedActivities}\n onActivityCreated={handleActivityCreated}\n onScheduleRequested={openNewScheduleDialog}\n onAddActivity={handleAddActivity}\n onMarkDone={handleMarkDone}\n onEditActivity={handleEditActivity}\n onCancelActivity={handleCancelActivity}\n runGuardedMutation={runMutationWithContext}\n refreshKey={activityRefreshKey}\n useCanonicalInteractions={useCanonicalInteractions}\n />\n )}\n\n {activeTab === 'changelog' && companyId && (\n <ChangelogTab entityId={companyId} entityType=\"company\" />\n )}\n\n {activeTab === 'files' && (\n <AttachmentsSection\n entityId={E.customers.customer_entity}\n recordId={companyId}\n title={t('customers.companies.detail.tabs.files', 'Files')}\n description={t('customers.companies.detail.files.subtitle', 'Upload and manage files linked to this company.')}\n />\n )}\n\n {/* Injected tabs from UMES */}\n {injectedTabMap.has(activeTab) && injectedTabMap.get(activeTab)!()}\n </CompanyDetailTabs>\n }\n />\n\n {/* UMES footer injection */}\n <InjectionSpot spotId=\"detail:customers.company:footer\" context={injectionContext} data={data} />\n\n {/* Schedule Activity Dialog */}\n <ScheduleActivityDialog\n open={scheduleDialogOpen}\n onClose={() => { setScheduleDialogOpen(false); setScheduleEditData(null) }}\n entityId={companyId}\n entityName={companyName}\n entityType=\"company\"\n onActivityCreated={handleActivityCreated}\n editData={scheduleEditData}\n />\n {ConfirmDialogElement}\n </div>\n </PageBody>\n </Page>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["companyId"]
|
|
7
7
|
}
|
|
@@ -192,12 +192,14 @@ function DealDetailPage({ params }) {
|
|
|
192
192
|
if (activity.entityId && activityEntities.some((entry) => entry.id === activity.entityId)) {
|
|
193
193
|
setSelectedActivityEntityId(activity.entityId);
|
|
194
194
|
}
|
|
195
|
+
const rawActivity = activity;
|
|
195
196
|
openScheduleEdit({
|
|
196
197
|
id: activity.id,
|
|
197
198
|
interactionType: activity.interactionType,
|
|
198
199
|
title: activity.title ?? null,
|
|
199
200
|
body: activity.body ?? null,
|
|
200
201
|
scheduledAt: activity.scheduledAt ?? null,
|
|
202
|
+
occurredAt: activity.occurredAt ?? null,
|
|
201
203
|
durationMinutes: activity.duration ?? null,
|
|
202
204
|
location: activity.location ?? null,
|
|
203
205
|
allDay: activity.allDay ?? null,
|
|
@@ -207,7 +209,9 @@ function DealDetailPage({ params }) {
|
|
|
207
209
|
reminderMinutes: activity.reminderMinutes ?? null,
|
|
208
210
|
visibility: activity.visibility ?? null,
|
|
209
211
|
linkedEntities: activity.linkedEntities ?? null,
|
|
210
|
-
guestPermissions: activity.guestPermissions ?? null
|
|
212
|
+
guestPermissions: activity.guestPermissions ?? null,
|
|
213
|
+
...rawActivity.customValues && typeof rawActivity.customValues === "object" ? { customValues: rawActivity.customValues } : {},
|
|
214
|
+
...typeof rawActivity.phoneNumber === "string" ? { phoneNumber: rawActivity.phoneNumber } : {}
|
|
211
215
|
});
|
|
212
216
|
}, [activityEntities, openScheduleEdit]);
|
|
213
217
|
const handleViewDashboard = React.useCallback(() => {
|