@open-mercato/core 0.4.5-develop-610fbb24ec → 0.4.5-develop-811deeb983
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/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +17 -2
- package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +15 -0
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +30 -0
- package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
- package/dist/modules/catalog/data/validators.js +4 -3
- package/dist/modules/catalog/data/validators.js.map +2 -2
- package/dist/modules/catalog/lib/messageObjectPreviews.js +146 -0
- package/dist/modules/catalog/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/catalog/message-objects.js +95 -0
- package/dist/modules/catalog/message-objects.js.map +7 -0
- package/dist/modules/currencies/backend/currencies/[id]/page.js +21 -0
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/lib/messageObjectPreviews.js +51 -0
- package/dist/modules/currencies/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/currencies/message-objects.js +41 -0
- package/dist/modules/currencies/message-objects.js.map +7 -0
- package/dist/modules/customers/backend/customers/companies/[id]/page.js +20 -0
- package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/[id]/page.js +12 -1
- package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +20 -0
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyHighlights.js +18 -14
- package/dist/modules/customers/components/detail/CompanyHighlights.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonHighlights.js +18 -14
- package/dist/modules/customers/components/detail/PersonHighlights.js.map +2 -2
- package/dist/modules/customers/lib/messageObjectPreviews.js +41 -5
- package/dist/modules/customers/lib/messageObjectPreviews.js.map +2 -2
- package/dist/modules/customers/message-objects.js +31 -11
- package/dist/modules/customers/message-objects.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +3 -0
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js +6 -1
- package/dist/modules/messages/components/message-detail/panels/objects-panel.js.map +2 -2
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js +4 -1
- package/dist/modules/messages/components/message-detail/panels/thread-panel.js.map +2 -2
- package/dist/modules/messages/frontend/messages/view/[token]/page.js +1 -0
- package/dist/modules/messages/frontend/messages/view/[token]/page.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +24 -7
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/resources/lib/messageObjectPreviews.js +43 -0
- package/dist/modules/resources/lib/messageObjectPreviews.js.map +7 -0
- package/dist/modules/resources/message-objects.js +37 -0
- package/dist/modules/resources/message-objects.js.map +7 -0
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +19 -0
- package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +23 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/quotes/[id]/page.js +1 -1
- package/dist/modules/sales/backend/sales/quotes/[id]/page.js.map +2 -2
- package/dist/modules/sales/lib/messageObjectPreviews.js +49 -4
- package/dist/modules/sales/lib/messageObjectPreviews.js.map +2 -2
- package/dist/modules/sales/message-objects.js +44 -2
- package/dist/modules/sales/message-objects.js.map +2 -2
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js +59 -30
- package/dist/modules/sales/widgets/messages/SalesDocumentMessageDetail.js.map +2 -2
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js +1 -1
- package/dist/modules/sales/widgets/messages/SalesDocumentMessagePreview.js.map +1 -1
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +8 -30
- package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-availability/page.js +13 -0
- package/dist/modules/staff/backend/staff/my-availability/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +8 -31
- package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +32 -10
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +14 -1
- package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +14 -1
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/components/TeamForm.js +4 -2
- package/dist/modules/staff/components/TeamForm.js.map +2 -2
- package/dist/modules/staff/components/TeamRoleForm.js +4 -2
- package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
- package/dist/modules/staff/lib/messageObjectPreviews.js +111 -2
- package/dist/modules/staff/lib/messageObjectPreviews.js.map +2 -2
- package/dist/modules/staff/message-objects.js +79 -8
- package/dist/modules/staff/message-objects.js.map +2 -2
- package/package.json +3 -3
- package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +19 -5
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +14 -0
- package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +40 -0
- package/src/modules/catalog/data/validators.ts +47 -45
- package/src/modules/catalog/lib/messageObjectPreviews.ts +176 -0
- package/src/modules/catalog/message-objects.ts +102 -0
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +20 -0
- package/src/modules/currencies/lib/messageObjectPreviews.ts +65 -0
- package/src/modules/currencies/message-objects.ts +40 -0
- package/src/modules/customers/backend/customers/companies/[id]/page.tsx +19 -0
- package/src/modules/customers/backend/customers/deals/[id]/page.tsx +13 -0
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +19 -0
- package/src/modules/customers/components/detail/CompanyHighlights.tsx +14 -9
- package/src/modules/customers/components/detail/PersonHighlights.tsx +14 -9
- package/src/modules/customers/lib/messageObjectPreviews.ts +43 -3
- package/src/modules/customers/message-objects.ts +31 -11
- package/src/modules/customers/migrations/.snapshot-open-mercato.json +236 -0
- package/src/modules/customers/migrations/.snapshot-openmercato.json +236 -0
- package/src/modules/messages/commands/messages.ts +4 -0
- package/src/modules/messages/components/message-detail/panels/objects-panel.tsx +8 -1
- package/src/modules/messages/components/message-detail/panels/thread-panel.tsx +3 -0
- package/src/modules/messages/frontend/messages/view/[token]/page.tsx +1 -0
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +20 -4
- package/src/modules/resources/lib/messageObjectPreviews.ts +55 -0
- package/src/modules/resources/message-objects.ts +36 -0
- package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +18 -0
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +23 -0
- package/src/modules/sales/backend/sales/quotes/[id]/page.tsx +1 -1
- package/src/modules/sales/lib/messageObjectPreviews.ts +54 -4
- package/src/modules/sales/message-objects.ts +44 -2
- package/src/modules/sales/widgets/messages/SalesDocumentMessageDetail.tsx +72 -34
- package/src/modules/sales/widgets/messages/SalesDocumentMessagePreview.tsx +1 -1
- package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +7 -29
- package/src/modules/staff/backend/staff/my-availability/page.tsx +14 -0
- package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +8 -30
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +28 -7
- package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +12 -0
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +12 -0
- package/src/modules/staff/components/TeamForm.tsx +3 -0
- package/src/modules/staff/components/TeamRoleForm.tsx +3 -0
- package/src/modules/staff/lib/messageObjectPreviews.ts +133 -2
- package/src/modules/staff/message-objects.ts +79 -8
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js +0 -51
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectDetail.js.map +0 -7
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js +0 -35
- package/dist/modules/customers/widgets/messages/CustomerMessageObjectPreview.js.map +0 -7
- package/dist/modules/customers/widgets/messages/index.js +0 -7
- package/dist/modules/customers/widgets/messages/index.js.map +0 -7
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js +0 -51
- package/dist/modules/staff/widgets/messages/StaffMessageObjectDetail.js.map +0 -7
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js +0 -34
- package/dist/modules/staff/widgets/messages/StaffMessageObjectPreview.js.map +0 -7
- package/dist/modules/staff/widgets/messages/index.js +0 -7
- package/dist/modules/staff/widgets/messages/index.js.map +0 -7
- package/src/modules/customers/widgets/messages/CustomerMessageObjectDetail.tsx +0 -57
- package/src/modules/customers/widgets/messages/CustomerMessageObjectPreview.tsx +0 -49
- package/src/modules/customers/widgets/messages/index.ts +0 -2
- package/src/modules/staff/widgets/messages/StaffMessageObjectDetail.tsx +0 -57
- package/src/modules/staff/widgets/messages/StaffMessageObjectPreview.tsx +0 -44
- package/src/modules/staff/widgets/messages/index.ts +0 -2
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
|
|
2
|
+
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
3
|
+
import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
|
|
4
|
+
import type { ObjectPreviewData } from '@open-mercato/shared/modules/messages/types'
|
|
5
|
+
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
6
|
+
import { Currency } from '../data/entities'
|
|
7
|
+
|
|
8
|
+
type PreviewContext = {
|
|
9
|
+
tenantId: string
|
|
10
|
+
organizationId?: string | null
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function resolveEm() {
|
|
14
|
+
const { resolve } = await createRequestContainer()
|
|
15
|
+
return resolve('em') as EntityManager
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function loadCurrencyPreview(
|
|
19
|
+
entityId: string,
|
|
20
|
+
ctx: PreviewContext,
|
|
21
|
+
): Promise<ObjectPreviewData> {
|
|
22
|
+
const { t } = await resolveTranslations()
|
|
23
|
+
const defaultTitle = t('currencies.messageObjects.currency.title')
|
|
24
|
+
|
|
25
|
+
if (!ctx.organizationId) {
|
|
26
|
+
return { title: defaultTitle, subtitle: entityId }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const em = await resolveEm()
|
|
30
|
+
const entity = await findOneWithDecryption(
|
|
31
|
+
em,
|
|
32
|
+
Currency,
|
|
33
|
+
{
|
|
34
|
+
id: entityId,
|
|
35
|
+
tenantId: ctx.tenantId,
|
|
36
|
+
organizationId: ctx.organizationId,
|
|
37
|
+
deletedAt: null,
|
|
38
|
+
},
|
|
39
|
+
undefined,
|
|
40
|
+
{ tenantId: ctx.tenantId, organizationId: ctx.organizationId },
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
if (!entity) {
|
|
44
|
+
return {
|
|
45
|
+
title: defaultTitle,
|
|
46
|
+
subtitle: entityId,
|
|
47
|
+
status: t('customers.messageObjects.notFound'),
|
|
48
|
+
statusColor: 'gray',
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const subtitleParts = [entity.code, entity.symbol]
|
|
53
|
+
.filter((part): part is string => Boolean(part && part.trim().length > 0))
|
|
54
|
+
const metadata: Record<string, string> = {}
|
|
55
|
+
const codeLabel = t('currencies.form.field.code')
|
|
56
|
+
const symbolLabel = t('currencies.form.field.symbol')
|
|
57
|
+
if (entity.code) metadata[codeLabel] = entity.code
|
|
58
|
+
if (entity.symbol) metadata[symbolLabel] = entity.symbol
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
title: entity.name,
|
|
62
|
+
subtitle: subtitleParts.join(' · ') || entityId,
|
|
63
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { MessageObjectTypeDefinition } from '@open-mercato/shared/modules/messages/types'
|
|
2
|
+
import { MessageObjectDetail, MessageObjectPreview } from '@open-mercato/ui/backend/messages'
|
|
3
|
+
|
|
4
|
+
const objectMessageTypes = ['default', 'messages.defaultWithObjects']
|
|
5
|
+
|
|
6
|
+
export const messageObjectTypes: MessageObjectTypeDefinition[] = [
|
|
7
|
+
{
|
|
8
|
+
module: 'currencies',
|
|
9
|
+
entityType: 'currency',
|
|
10
|
+
messageTypes: objectMessageTypes,
|
|
11
|
+
entityId: 'currencies:currency',
|
|
12
|
+
optionLabelField: 'name',
|
|
13
|
+
optionSubtitleField: 'code',
|
|
14
|
+
labelKey: 'currencies.messageObjects.currency.title',
|
|
15
|
+
icon: 'coins',
|
|
16
|
+
PreviewComponent: MessageObjectPreview,
|
|
17
|
+
DetailComponent: MessageObjectDetail,
|
|
18
|
+
actions: [
|
|
19
|
+
{
|
|
20
|
+
id: 'view',
|
|
21
|
+
labelKey: 'common.view',
|
|
22
|
+
variant: 'outline',
|
|
23
|
+
href: '/backend/currencies/{entityId}',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
loadPreview: async (entityId, ctx) => {
|
|
27
|
+
if (typeof window !== 'undefined') {
|
|
28
|
+
return {
|
|
29
|
+
title: 'Currency',
|
|
30
|
+
subtitle: entityId,
|
|
31
|
+
metadata: { id: entityId },
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const { loadCurrencyPreview } = await import('./lib/messageObjectPreviews')
|
|
35
|
+
return loadCurrencyPreview(entityId, ctx)
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
export default messageObjectTypes
|
|
@@ -49,6 +49,7 @@ import { readMarkdownPreferenceCookie, writeMarkdownPreferenceCookie } from '../
|
|
|
49
49
|
import { InjectionSpot, useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'
|
|
50
50
|
import { DetailTabsLayout } from '../../../../components/detail/DetailTabsLayout'
|
|
51
51
|
import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
|
|
52
|
+
import { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'
|
|
52
53
|
|
|
53
54
|
type CompanyOverview = {
|
|
54
55
|
company: {
|
|
@@ -730,6 +731,24 @@ export default function CustomerCompanyDetailPage({ params }: { params?: { id?:
|
|
|
730
731
|
profile={profile ?? null}
|
|
731
732
|
validators={validators}
|
|
732
733
|
onDisplayNameSave={updateDisplayName}
|
|
734
|
+
utilityActions={(
|
|
735
|
+
<SendObjectMessageDialog
|
|
736
|
+
object={{
|
|
737
|
+
entityModule: 'customers',
|
|
738
|
+
entityType: 'company',
|
|
739
|
+
entityId: companyId,
|
|
740
|
+
previewData: {
|
|
741
|
+
title: company.displayName,
|
|
742
|
+
subtitle: company.primaryEmail ?? undefined,
|
|
743
|
+
metadata: {
|
|
744
|
+
[t('customers.companies.detail.highlights.primaryPhone')]: company.primaryPhone ?? '-',
|
|
745
|
+
[t('customers.companies.detail.fields.industry')]: profile?.industry ?? '-',
|
|
746
|
+
},
|
|
747
|
+
},
|
|
748
|
+
}}
|
|
749
|
+
viewHref={`/backend/customers/companies/${companyId}`}
|
|
750
|
+
/>
|
|
751
|
+
)}
|
|
733
752
|
onPrimaryEmailSave={(value) => updateCompanyField('primaryEmail', value)}
|
|
734
753
|
onPrimaryPhoneSave={(value) => updateCompanyField('primaryPhone', value)}
|
|
735
754
|
onStatusSave={(value) => updateCompanyField('status', value)}
|
|
@@ -380,6 +380,13 @@ export default function DealDetailPage({ params }: { params?: { id?: string } })
|
|
|
380
380
|
const statusDictEntry = data.deal.status ? statusDictionaryMap?.[data.deal.status] ?? null : null
|
|
381
381
|
const pipelineLabel = resolveDictionaryLabel(data.deal.pipelineStage, pipelineDictionaryMap)
|
|
382
382
|
const pipelineDictEntry = data.deal.pipelineStage ? pipelineDictionaryMap?.[data.deal.pipelineStage] ?? null : null
|
|
383
|
+
const previewValueAmount = formatCurrency(data.deal.valueAmount, data.deal.valueCurrency)
|
|
384
|
+
const previewProbability = data.deal.probability !== null && data.deal.probability !== undefined
|
|
385
|
+
? `${data.deal.probability}%`
|
|
386
|
+
: null
|
|
387
|
+
const dealPreviewMetadata: Record<string, string> = {}
|
|
388
|
+
if (previewValueAmount) dealPreviewMetadata[t('customers.deals.detail.fields.value')] = previewValueAmount
|
|
389
|
+
if (previewProbability) dealPreviewMetadata[t('customers.deals.detail.fields.probability')] = previewProbability
|
|
383
390
|
|
|
384
391
|
const peopleSummaryLabel =
|
|
385
392
|
data.people.length === 1
|
|
@@ -409,7 +416,13 @@ export default function DealDetailPage({ params }: { params?: { id?: string } })
|
|
|
409
416
|
entityId: data.deal.id,
|
|
410
417
|
sourceEntityType: 'customers.deal',
|
|
411
418
|
sourceEntityId: data.deal.id,
|
|
419
|
+
previewData: {
|
|
420
|
+
title: data.deal.title || t('customers.deals.detail.untitled', 'Untitled deal'),
|
|
421
|
+
status: data.deal.status ? statusLabel : undefined,
|
|
422
|
+
metadata: Object.keys(dealPreviewMetadata).length > 0 ? dealPreviewMetadata : undefined,
|
|
423
|
+
},
|
|
412
424
|
}}
|
|
425
|
+
viewHref={`/backend/customers/deals/${data.deal.id}`}
|
|
413
426
|
defaultValues={{
|
|
414
427
|
sourceEntityType: 'customers.deal',
|
|
415
428
|
sourceEntityId: data.deal.id,
|
|
@@ -48,6 +48,7 @@ import { readMarkdownPreferenceCookie, writeMarkdownPreferenceCookie } from '../
|
|
|
48
48
|
import { InjectionSpot, useInjectionWidgets } from '@open-mercato/ui/backend/injection/InjectionSpot'
|
|
49
49
|
import { DetailTabsLayout } from '../../../../components/detail/DetailTabsLayout'
|
|
50
50
|
import { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'
|
|
51
|
+
import { SendObjectMessageDialog } from '@open-mercato/ui/backend/messages'
|
|
51
52
|
|
|
52
53
|
type PersonOverview = {
|
|
53
54
|
person: {
|
|
@@ -656,6 +657,24 @@ export default function CustomerPersonDetailPage({ params }: { params?: { id?: s
|
|
|
656
657
|
phone: validators.phone,
|
|
657
658
|
displayName: validators.displayName,
|
|
658
659
|
}}
|
|
660
|
+
utilityActions={(
|
|
661
|
+
<SendObjectMessageDialog
|
|
662
|
+
object={{
|
|
663
|
+
entityModule: 'customers',
|
|
664
|
+
entityType: 'person',
|
|
665
|
+
entityId: personId,
|
|
666
|
+
previewData: {
|
|
667
|
+
title: person.displayName,
|
|
668
|
+
subtitle: person.primaryEmail ?? undefined,
|
|
669
|
+
metadata: {
|
|
670
|
+
[t('customers.people.detail.highlights.primaryPhone')]: person.primaryPhone ?? '-',
|
|
671
|
+
[t('customers.people.detail.fields.jobTitle')]: profile?.jobTitle ?? '-',
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
}}
|
|
675
|
+
viewHref={`/backend/customers/people/${personId}`}
|
|
676
|
+
/>
|
|
677
|
+
)}
|
|
659
678
|
onDisplayNameSave={updateDisplayName}
|
|
660
679
|
onPrimaryEmailSave={async (next) => {
|
|
661
680
|
const send = typeof next === 'string' ? next : ''
|
|
@@ -52,6 +52,7 @@ export type CompanyHighlightsProps = {
|
|
|
52
52
|
onNextInteractionSave: (payload: NextInteractionPayload | null) => Promise<void>
|
|
53
53
|
onDelete: () => void
|
|
54
54
|
isDeleting: boolean
|
|
55
|
+
utilityActions?: React.ReactNode
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
export function CompanyHighlights({
|
|
@@ -65,6 +66,7 @@ export function CompanyHighlights({
|
|
|
65
66
|
onNextInteractionSave,
|
|
66
67
|
onDelete,
|
|
67
68
|
isDeleting,
|
|
69
|
+
utilityActions,
|
|
68
70
|
}: CompanyHighlightsProps) {
|
|
69
71
|
const t = useT()
|
|
70
72
|
const historyFallbackId =
|
|
@@ -77,15 +79,18 @@ export function CompanyHighlights({
|
|
|
77
79
|
backHref="/backend/customers/companies"
|
|
78
80
|
backLabel={t('customers.companies.detail.actions.backToList', 'Back to companies')}
|
|
79
81
|
utilityActions={(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
82
|
+
<>
|
|
83
|
+
{utilityActions}
|
|
84
|
+
<VersionHistoryAction
|
|
85
|
+
config={{
|
|
86
|
+
resourceKind: 'customers.company',
|
|
87
|
+
resourceId: company.id,
|
|
88
|
+
resourceIdFallback: historyFallbackId,
|
|
89
|
+
organizationId: company.organizationId ?? undefined,
|
|
90
|
+
}}
|
|
91
|
+
t={t}
|
|
92
|
+
/>
|
|
93
|
+
</>
|
|
89
94
|
)}
|
|
90
95
|
title={
|
|
91
96
|
<InlineTextEditor
|
|
@@ -55,6 +55,7 @@ export type PersonHighlightsProps = {
|
|
|
55
55
|
onDelete: () => void
|
|
56
56
|
isDeleting: boolean
|
|
57
57
|
onCompanySave: (companyId: string | null) => Promise<void>
|
|
58
|
+
utilityActions?: React.ReactNode
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
type CompanyInfo = { id: string; name: string }
|
|
@@ -71,6 +72,7 @@ export function PersonHighlights({
|
|
|
71
72
|
onDelete,
|
|
72
73
|
isDeleting,
|
|
73
74
|
onCompanySave,
|
|
75
|
+
utilityActions,
|
|
74
76
|
}: PersonHighlightsProps) {
|
|
75
77
|
const router = useRouter()
|
|
76
78
|
const t = useT()
|
|
@@ -339,15 +341,18 @@ export function PersonHighlights({
|
|
|
339
341
|
backHref="/backend/customers/people"
|
|
340
342
|
backLabel={t('customers.people.detail.actions.backToList')}
|
|
341
343
|
utilityActions={(
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
344
|
+
<>
|
|
345
|
+
{utilityActions}
|
|
346
|
+
<VersionHistoryAction
|
|
347
|
+
config={{
|
|
348
|
+
resourceKind: 'customers.person',
|
|
349
|
+
resourceId: person.id,
|
|
350
|
+
resourceIdFallback: historyFallbackId,
|
|
351
|
+
organizationId: person.organizationId ?? undefined,
|
|
352
|
+
}}
|
|
353
|
+
t={t}
|
|
354
|
+
/>
|
|
355
|
+
</>
|
|
351
356
|
)}
|
|
352
357
|
title={
|
|
353
358
|
<InlineTextEditor
|
|
@@ -3,7 +3,7 @@ import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
|
3
3
|
import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
|
|
4
4
|
import type { ObjectPreviewData } from '@open-mercato/shared/modules/messages/types'
|
|
5
5
|
import type { EntityManager } from '@mikro-orm/postgresql'
|
|
6
|
-
import { CustomerDeal, CustomerEntity } from '../data/entities'
|
|
6
|
+
import { CustomerCompanyProfile, CustomerDeal, CustomerEntity, CustomerPersonProfile } from '../data/entities'
|
|
7
7
|
|
|
8
8
|
type PreviewContext = {
|
|
9
9
|
tenantId: string
|
|
@@ -63,13 +63,32 @@ export async function loadCustomerPersonPreview(entityId: string, ctx: PreviewCo
|
|
|
63
63
|
return { title: defaultTitle, subtitle: entityId, status: t('customers.messageObjects.notFound'), statusColor: 'gray' }
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
const profile = await findOneWithDecryption(
|
|
67
|
+
em,
|
|
68
|
+
CustomerPersonProfile,
|
|
69
|
+
{
|
|
70
|
+
entity,
|
|
71
|
+
tenantId: ctx.tenantId,
|
|
72
|
+
organizationId: ctx.organizationId,
|
|
73
|
+
},
|
|
74
|
+
undefined,
|
|
75
|
+
{ tenantId: ctx.tenantId, organizationId: ctx.organizationId },
|
|
76
|
+
)
|
|
77
|
+
|
|
66
78
|
const subtitleParts = [entity.primaryEmail, entity.primaryPhone]
|
|
67
79
|
.filter((part): part is string => Boolean(part && part.trim().length > 0))
|
|
80
|
+
const metadata: Record<string, string> = {}
|
|
81
|
+
const phoneLabel = t('customers.people.detail.highlights.primaryPhone')
|
|
82
|
+
const jobTitleLabel = t('customers.people.detail.fields.jobTitle')
|
|
83
|
+
if (entity.primaryPhone && entity.primaryPhone.trim().length > 0) metadata[phoneLabel] = entity.primaryPhone
|
|
84
|
+
if (profile?.jobTitle && profile.jobTitle.trim().length > 0) metadata[jobTitleLabel] = profile.jobTitle
|
|
85
|
+
|
|
68
86
|
return {
|
|
69
87
|
title: entity.displayName,
|
|
70
88
|
subtitle: subtitleParts.join(' • ') || entityId,
|
|
71
89
|
status: entity.status ?? undefined,
|
|
72
90
|
statusColor: statusColor(entity.status),
|
|
91
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
73
92
|
}
|
|
74
93
|
}
|
|
75
94
|
|
|
@@ -100,13 +119,32 @@ export async function loadCustomerCompanyPreview(entityId: string, ctx: PreviewC
|
|
|
100
119
|
return { title: defaultTitle, subtitle: entityId, status: t('customers.messageObjects.notFound'), statusColor: 'gray' }
|
|
101
120
|
}
|
|
102
121
|
|
|
122
|
+
const profile = await findOneWithDecryption(
|
|
123
|
+
em,
|
|
124
|
+
CustomerCompanyProfile,
|
|
125
|
+
{
|
|
126
|
+
entity,
|
|
127
|
+
tenantId: ctx.tenantId,
|
|
128
|
+
organizationId: ctx.organizationId,
|
|
129
|
+
},
|
|
130
|
+
undefined,
|
|
131
|
+
{ tenantId: ctx.tenantId, organizationId: ctx.organizationId },
|
|
132
|
+
)
|
|
133
|
+
|
|
103
134
|
const subtitleParts = [entity.primaryEmail, entity.primaryPhone]
|
|
104
135
|
.filter((part): part is string => Boolean(part && part.trim().length > 0))
|
|
136
|
+
const metadata: Record<string, string> = {}
|
|
137
|
+
const phoneLabel = t('customers.companies.detail.highlights.primaryPhone')
|
|
138
|
+
const industryLabel = t('customers.companies.detail.fields.industry')
|
|
139
|
+
if (entity.primaryPhone && entity.primaryPhone.trim().length > 0) metadata[phoneLabel] = entity.primaryPhone
|
|
140
|
+
if (profile?.industry && profile.industry.trim().length > 0) metadata[industryLabel] = profile.industry
|
|
141
|
+
|
|
105
142
|
return {
|
|
106
143
|
title: entity.displayName,
|
|
107
144
|
subtitle: subtitleParts.join(' • ') || entityId,
|
|
108
145
|
status: entity.status ?? undefined,
|
|
109
146
|
statusColor: statusColor(entity.status),
|
|
147
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
110
148
|
}
|
|
111
149
|
}
|
|
112
150
|
|
|
@@ -140,8 +178,10 @@ export async function loadCustomerDealPreview(entityId: string, ctx: PreviewCont
|
|
|
140
178
|
const probability = typeof deal.probability === 'number' ? `${deal.probability}%` : null
|
|
141
179
|
const subtitle = [amount, probability].filter((part): part is string => Boolean(part && part.length > 0)).join(' • ')
|
|
142
180
|
const metadata: Record<string, string> = {}
|
|
143
|
-
|
|
144
|
-
|
|
181
|
+
const valueLabel = t('customers.deals.detail.fields.value')
|
|
182
|
+
const probabilityLabel = t('customers.deals.detail.fields.probability')
|
|
183
|
+
if (amount) metadata[valueLabel] = amount
|
|
184
|
+
if (probability) metadata[probabilityLabel] = probability
|
|
145
185
|
|
|
146
186
|
return {
|
|
147
187
|
title: deal.title,
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { MessageObjectTypeDefinition } from '@open-mercato/shared/modules/messages/types'
|
|
2
|
-
import {
|
|
3
|
-
import { CustomerMessageObjectPreview } from './widgets/messages/CustomerMessageObjectPreview'
|
|
2
|
+
import { MessageObjectDetail, MessageObjectPreview } from '@open-mercato/ui'
|
|
4
3
|
|
|
5
4
|
const objectMessageTypes = ['default', 'messages.defaultWithObjects']
|
|
6
5
|
|
|
@@ -14,9 +13,16 @@ export const messageObjectTypes: MessageObjectTypeDefinition[] = [
|
|
|
14
13
|
optionSubtitleField: 'email',
|
|
15
14
|
labelKey: 'customers.people.list.title',
|
|
16
15
|
icon: 'user-round',
|
|
17
|
-
PreviewComponent:
|
|
18
|
-
DetailComponent:
|
|
19
|
-
actions: [
|
|
16
|
+
PreviewComponent: MessageObjectPreview,
|
|
17
|
+
DetailComponent: MessageObjectDetail,
|
|
18
|
+
actions: [
|
|
19
|
+
{
|
|
20
|
+
id: 'view',
|
|
21
|
+
labelKey: 'common.view',
|
|
22
|
+
variant: 'outline',
|
|
23
|
+
href: '/backend/customers/people/{entityId}',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
20
26
|
loadPreview: async (entityId, ctx) => {
|
|
21
27
|
if (typeof window !== 'undefined') {
|
|
22
28
|
return { title: 'Person', subtitle: entityId }
|
|
@@ -34,9 +40,16 @@ export const messageObjectTypes: MessageObjectTypeDefinition[] = [
|
|
|
34
40
|
optionSubtitleField: 'taxId',
|
|
35
41
|
labelKey: 'customers.companies.list.title',
|
|
36
42
|
icon: 'building2',
|
|
37
|
-
PreviewComponent:
|
|
38
|
-
DetailComponent:
|
|
39
|
-
actions: [
|
|
43
|
+
PreviewComponent: MessageObjectPreview,
|
|
44
|
+
DetailComponent: MessageObjectDetail,
|
|
45
|
+
actions: [
|
|
46
|
+
{
|
|
47
|
+
id: 'view',
|
|
48
|
+
labelKey: 'common.view',
|
|
49
|
+
variant: 'outline',
|
|
50
|
+
href: '/backend/customers/companies/{entityId}',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
40
53
|
loadPreview: async (entityId, ctx) => {
|
|
41
54
|
if (typeof window !== 'undefined') {
|
|
42
55
|
return { title: 'Company', subtitle: entityId }
|
|
@@ -54,9 +67,16 @@ export const messageObjectTypes: MessageObjectTypeDefinition[] = [
|
|
|
54
67
|
optionSubtitleField: 'status',
|
|
55
68
|
labelKey: 'customers.deals.list.title',
|
|
56
69
|
icon: 'briefcase-business',
|
|
57
|
-
PreviewComponent:
|
|
58
|
-
DetailComponent:
|
|
59
|
-
actions: [
|
|
70
|
+
PreviewComponent: MessageObjectPreview,
|
|
71
|
+
DetailComponent: MessageObjectDetail,
|
|
72
|
+
actions: [
|
|
73
|
+
{
|
|
74
|
+
id: 'view',
|
|
75
|
+
labelKey: 'common.view',
|
|
76
|
+
variant: 'outline',
|
|
77
|
+
href: '/backend/customers/deals/{entityId}',
|
|
78
|
+
},
|
|
79
|
+
],
|
|
60
80
|
loadPreview: async (entityId, ctx) => {
|
|
61
81
|
if (typeof window !== 'undefined') {
|
|
62
82
|
return { title: 'Deal', subtitle: entityId }
|