@open-mercato/core 0.10.1-develop.7763.1.caea616ebf → 0.10.1-develop.7764.1.7505d7340b
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/dist/modules/customers/api/companies/route.js +2 -1
- package/dist/modules/customers/api/companies/route.js.map +2 -2
- package/dist/modules/customers/api/people/route.js +2 -1
- package/dist/modules/customers/api/people/route.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies/page.js +21 -3
- package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/listSorting.js +2 -1
- package/dist/modules/customers/backend/customers/listSorting.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/page.js +17 -1
- package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
- package/dist/modules/customers/lib/createdAtDayFilter.js +64 -0
- package/dist/modules/customers/lib/createdAtDayFilter.js.map +7 -0
- package/package.json +7 -7
- package/src/modules/customers/api/companies/route.ts +2 -1
- package/src/modules/customers/api/people/route.ts +2 -1
- package/src/modules/customers/backend/customers/companies/page.tsx +26 -3
- package/src/modules/customers/backend/customers/listSorting.ts +1 -0
- package/src/modules/customers/backend/customers/people/page.tsx +22 -1
- package/src/modules/customers/i18n/de.json +2 -0
- package/src/modules/customers/i18n/en.json +2 -0
- package/src/modules/customers/i18n/es.json +2 -0
- package/src/modules/customers/i18n/ko.json +2 -0
- package/src/modules/customers/i18n/pl.json +2 -0
- package/src/modules/customers/lib/createdAtDayFilter.ts +68 -0
|
@@ -58,6 +58,8 @@ import {
|
|
|
58
58
|
} from '../../../components/detail/assignableStaff'
|
|
59
59
|
import { CollectionPreviewCell, normalizeCollectionLabels } from '../../../components/list/CollectionPreviewCell'
|
|
60
60
|
import { appendCustomerListSortParams } from '../listSorting'
|
|
61
|
+
import { expandCreatedAtDayRules } from '../../../lib/createdAtDayFilter'
|
|
62
|
+
import { USER_TIMEZONE } from '../../../lib/localDay'
|
|
61
63
|
|
|
62
64
|
type DictionaryOptionWithTone = AdvancedFilterOption & FilterOption
|
|
63
65
|
|
|
@@ -119,6 +121,7 @@ type PersonRow = {
|
|
|
119
121
|
organizationId?: string | null
|
|
120
122
|
source?: string | null
|
|
121
123
|
ownerUserId?: string | null
|
|
124
|
+
createdAt?: string | null
|
|
122
125
|
} & Record<string, unknown>
|
|
123
126
|
|
|
124
127
|
type PeopleResponse = {
|
|
@@ -166,6 +169,7 @@ function mapApiItem(item: Record<string, unknown>): PersonRow | null {
|
|
|
166
169
|
const nextInteractionColor = typeof item.next_interaction_color === 'string' ? item.next_interaction_color : null
|
|
167
170
|
const organizationId = typeof item.organization_id === 'string' ? item.organization_id : null
|
|
168
171
|
const source = typeof item.source === 'string' ? item.source : null
|
|
172
|
+
const createdAt = typeof item.created_at === 'string' ? item.created_at : null
|
|
169
173
|
const customFields: Record<string, unknown> = {}
|
|
170
174
|
for (const [key, value] of Object.entries(item)) {
|
|
171
175
|
if (key.startsWith('cf_')) {
|
|
@@ -196,6 +200,7 @@ function mapApiItem(item: Record<string, unknown>): PersonRow | null {
|
|
|
196
200
|
nextInteractionColor,
|
|
197
201
|
organizationId,
|
|
198
202
|
source,
|
|
203
|
+
createdAt,
|
|
199
204
|
...customFields,
|
|
200
205
|
}, item)
|
|
201
206
|
}
|
|
@@ -375,7 +380,7 @@ export default function CustomersPeoplePage() {
|
|
|
375
380
|
params.set('pageSize', String(pageSize))
|
|
376
381
|
appendCustomerListSortParams(params, sorting)
|
|
377
382
|
if (search.trim()) params.set('search', search.trim())
|
|
378
|
-
const advancedParams = serializeTree(advancedFilterState)
|
|
383
|
+
const advancedParams = serializeTree(expandCreatedAtDayRules(advancedFilterState, USER_TIMEZONE))
|
|
379
384
|
for (const [key, val] of Object.entries(advancedParams)) {
|
|
380
385
|
params.set(key, val)
|
|
381
386
|
}
|
|
@@ -713,6 +718,22 @@ export default function CustomersPeoplePage() {
|
|
|
713
718
|
)
|
|
714
719
|
: <span className="text-muted-foreground text-sm">{t('customers.people.list.noValue')}</span>,
|
|
715
720
|
},
|
|
721
|
+
{
|
|
722
|
+
accessorKey: 'createdAt',
|
|
723
|
+
header: t('customers.people.list.columns.createdAt', 'Created'),
|
|
724
|
+
meta: {
|
|
725
|
+
columnChooserGroup: t('customers.columnGroups.dates', 'Dates'),
|
|
726
|
+
filterKey: 'created_at',
|
|
727
|
+
filterType: 'date' as const,
|
|
728
|
+
filterGroup: t('customers.columnGroups.activity', 'Activity'),
|
|
729
|
+
filterIconName: 'calendar',
|
|
730
|
+
},
|
|
731
|
+
cell: ({ row }) => (
|
|
732
|
+
<span className="text-sm">
|
|
733
|
+
{formatDate(row.original.createdAt, t('customers.people.list.noValue'))}
|
|
734
|
+
</span>
|
|
735
|
+
),
|
|
736
|
+
},
|
|
716
737
|
{
|
|
717
738
|
accessorKey: 'source',
|
|
718
739
|
header: t('customers.people.list.columns.source'),
|
|
@@ -797,6 +797,7 @@
|
|
|
797
797
|
"customers.companies.list.bulkDelete.progressName": "Ausgewählte Unternehmen löschen",
|
|
798
798
|
"customers.companies.list.bulkDelete.success": "{count} companies deleted",
|
|
799
799
|
"customers.companies.list.bulkDelete.title": "Delete {count} companies?",
|
|
800
|
+
"customers.companies.list.columns.createdAt": "Erstellt am",
|
|
800
801
|
"customers.companies.list.columns.email": "E-Mail",
|
|
801
802
|
"customers.companies.list.columns.lifecycleStage": "Lebenszyklusphase",
|
|
802
803
|
"customers.companies.list.columns.name": "Name",
|
|
@@ -2512,6 +2513,7 @@
|
|
|
2512
2513
|
"customers.people.list.bulkDelete.progressName": "Ausgewählte Personen löschen",
|
|
2513
2514
|
"customers.people.list.bulkDelete.success": "{count} people deleted",
|
|
2514
2515
|
"customers.people.list.bulkDelete.title": "Delete {count} people?",
|
|
2516
|
+
"customers.people.list.columns.createdAt": "Erstellt am",
|
|
2515
2517
|
"customers.people.list.columns.email": "E-Mail",
|
|
2516
2518
|
"customers.people.list.columns.lifecycleStage": "Lebenszyklusphase",
|
|
2517
2519
|
"customers.people.list.columns.name": "Name",
|
|
@@ -797,6 +797,7 @@
|
|
|
797
797
|
"customers.companies.list.bulkDelete.progressName": "Delete selected companies",
|
|
798
798
|
"customers.companies.list.bulkDelete.success": "{count} companies deleted",
|
|
799
799
|
"customers.companies.list.bulkDelete.title": "Delete {count} companies?",
|
|
800
|
+
"customers.companies.list.columns.createdAt": "Created",
|
|
800
801
|
"customers.companies.list.columns.email": "Email",
|
|
801
802
|
"customers.companies.list.columns.lifecycleStage": "Lifecycle stage",
|
|
802
803
|
"customers.companies.list.columns.name": "Name",
|
|
@@ -2512,6 +2513,7 @@
|
|
|
2512
2513
|
"customers.people.list.bulkDelete.progressName": "Delete selected people",
|
|
2513
2514
|
"customers.people.list.bulkDelete.success": "{count} people deleted",
|
|
2514
2515
|
"customers.people.list.bulkDelete.title": "Delete {count} people?",
|
|
2516
|
+
"customers.people.list.columns.createdAt": "Created",
|
|
2515
2517
|
"customers.people.list.columns.email": "Email",
|
|
2516
2518
|
"customers.people.list.columns.lifecycleStage": "Lifecycle stage",
|
|
2517
2519
|
"customers.people.list.columns.name": "Name",
|
|
@@ -797,6 +797,7 @@
|
|
|
797
797
|
"customers.companies.list.bulkDelete.progressName": "Eliminar empresas seleccionadas",
|
|
798
798
|
"customers.companies.list.bulkDelete.success": "{count} companies deleted",
|
|
799
799
|
"customers.companies.list.bulkDelete.title": "Delete {count} companies?",
|
|
800
|
+
"customers.companies.list.columns.createdAt": "Fecha de creación",
|
|
800
801
|
"customers.companies.list.columns.email": "Correo electrónico",
|
|
801
802
|
"customers.companies.list.columns.lifecycleStage": "Etapa del ciclo de vida",
|
|
802
803
|
"customers.companies.list.columns.name": "Nombre",
|
|
@@ -2512,6 +2513,7 @@
|
|
|
2512
2513
|
"customers.people.list.bulkDelete.progressName": "Eliminar personas seleccionadas",
|
|
2513
2514
|
"customers.people.list.bulkDelete.success": "{count} people deleted",
|
|
2514
2515
|
"customers.people.list.bulkDelete.title": "Delete {count} people?",
|
|
2516
|
+
"customers.people.list.columns.createdAt": "Fecha de creación",
|
|
2515
2517
|
"customers.people.list.columns.email": "Correo electrónico",
|
|
2516
2518
|
"customers.people.list.columns.lifecycleStage": "Etapa del ciclo de vida",
|
|
2517
2519
|
"customers.people.list.columns.name": "Nombre",
|
|
@@ -797,6 +797,7 @@
|
|
|
797
797
|
"customers.companies.list.bulkDelete.progressName": "선택한 회사 삭제",
|
|
798
798
|
"customers.companies.list.bulkDelete.success": "회사 {count}개가 삭제되었습니다",
|
|
799
799
|
"customers.companies.list.bulkDelete.title": "회사 {count}개를 삭제하시겠습니까?",
|
|
800
|
+
"customers.companies.list.columns.createdAt": "생성일",
|
|
800
801
|
"customers.companies.list.columns.email": "이메일",
|
|
801
802
|
"customers.companies.list.columns.lifecycleStage": "라이프사이클 단계",
|
|
802
803
|
"customers.companies.list.columns.name": "이름",
|
|
@@ -2512,6 +2513,7 @@
|
|
|
2512
2513
|
"customers.people.list.bulkDelete.progressName": "선택한 연락처 삭제",
|
|
2513
2514
|
"customers.people.list.bulkDelete.success": "{count}명의 연락처가 삭제되었습니다",
|
|
2514
2515
|
"customers.people.list.bulkDelete.title": "{count}명의 연락처를 삭제하시겠습니까?",
|
|
2516
|
+
"customers.people.list.columns.createdAt": "생성일",
|
|
2515
2517
|
"customers.people.list.columns.email": "이메일",
|
|
2516
2518
|
"customers.people.list.columns.lifecycleStage": "라이프사이클 단계",
|
|
2517
2519
|
"customers.people.list.columns.name": "이름",
|
|
@@ -797,6 +797,7 @@
|
|
|
797
797
|
"customers.companies.list.bulkDelete.progressName": "Usuń zaznaczone firmy",
|
|
798
798
|
"customers.companies.list.bulkDelete.success": "Usunięto {count} firm",
|
|
799
799
|
"customers.companies.list.bulkDelete.title": "Usunąć {count} firm?",
|
|
800
|
+
"customers.companies.list.columns.createdAt": "Data utworzenia",
|
|
800
801
|
"customers.companies.list.columns.email": "E-mail",
|
|
801
802
|
"customers.companies.list.columns.lifecycleStage": "Etap cyklu życia",
|
|
802
803
|
"customers.companies.list.columns.name": "Nazwa",
|
|
@@ -2512,6 +2513,7 @@
|
|
|
2512
2513
|
"customers.people.list.bulkDelete.progressName": "Usuń zaznaczone osoby",
|
|
2513
2514
|
"customers.people.list.bulkDelete.success": "Usunięto {count} osób",
|
|
2514
2515
|
"customers.people.list.bulkDelete.title": "Usunąć {count} osób?",
|
|
2516
|
+
"customers.people.list.columns.createdAt": "Data utworzenia",
|
|
2515
2517
|
"customers.people.list.columns.email": "E-mail",
|
|
2516
2518
|
"customers.people.list.columns.lifecycleStage": "Etap cyklu życia",
|
|
2517
2519
|
"customers.people.list.columns.name": "Nazwa",
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { fromZonedTime } from 'date-fns-tz'
|
|
2
|
+
import type { AdvancedFilterTree, FilterGroup, FilterRule } from '@open-mercato/shared/lib/query/advanced-filter-tree'
|
|
3
|
+
|
|
4
|
+
const CREATED_AT_FIELD = 'created_at'
|
|
5
|
+
const DATE_ONLY_PATTERN = /^\d{4}-\d{2}-\d{2}$/
|
|
6
|
+
|
|
7
|
+
function isDateOnly(value: unknown): value is string {
|
|
8
|
+
return typeof value === 'string' && DATE_ONLY_PATTERN.test(value.trim())
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function startOfDay(value: string, timeZone: string): string {
|
|
12
|
+
return fromZonedTime(`${value.trim()}T00:00:00.000`, timeZone).toISOString()
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function endOfDay(value: string, timeZone: string): string {
|
|
16
|
+
return fromZonedTime(`${value.trim()}T23:59:59.999`, timeZone).toISOString()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function expandRule(rule: FilterRule, timeZone: string): FilterRule {
|
|
20
|
+
if (rule.field !== CREATED_AT_FIELD) return rule
|
|
21
|
+
switch (rule.operator) {
|
|
22
|
+
case 'is':
|
|
23
|
+
case 'equals':
|
|
24
|
+
if (!isDateOnly(rule.value)) return rule
|
|
25
|
+
return { ...rule, operator: 'between', value: [startOfDay(rule.value, timeZone), endOfDay(rule.value, timeZone)] }
|
|
26
|
+
case 'is_after':
|
|
27
|
+
case 'greater_than':
|
|
28
|
+
if (!isDateOnly(rule.value)) return rule
|
|
29
|
+
return { ...rule, operator: 'greater_than', value: endOfDay(rule.value, timeZone) }
|
|
30
|
+
case 'less_or_equal':
|
|
31
|
+
if (!isDateOnly(rule.value)) return rule
|
|
32
|
+
return { ...rule, value: endOfDay(rule.value, timeZone) }
|
|
33
|
+
case 'is_before':
|
|
34
|
+
case 'less_than':
|
|
35
|
+
if (!isDateOnly(rule.value)) return rule
|
|
36
|
+
return { ...rule, operator: 'less_than', value: startOfDay(rule.value, timeZone) }
|
|
37
|
+
case 'greater_or_equal':
|
|
38
|
+
if (!isDateOnly(rule.value)) return rule
|
|
39
|
+
return { ...rule, value: startOfDay(rule.value, timeZone) }
|
|
40
|
+
case 'between': {
|
|
41
|
+
if (!Array.isArray(rule.value) || rule.value.length !== 2) return rule
|
|
42
|
+
const [start, end] = rule.value
|
|
43
|
+
return {
|
|
44
|
+
...rule,
|
|
45
|
+
value: [
|
|
46
|
+
isDateOnly(start) ? startOfDay(start, timeZone) : start,
|
|
47
|
+
isDateOnly(end) ? endOfDay(end, timeZone) : end,
|
|
48
|
+
],
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
default:
|
|
52
|
+
return rule
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function expandGroup(group: FilterGroup, timeZone: string): FilterGroup {
|
|
57
|
+
return {
|
|
58
|
+
...group,
|
|
59
|
+
children: group.children.map((child) =>
|
|
60
|
+
child.type === 'group' ? expandGroup(child, timeZone) : expandRule(child, timeZone),
|
|
61
|
+
),
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function expandCreatedAtDayRules<T extends AdvancedFilterTree | null>(tree: T, timeZone: string): T {
|
|
66
|
+
if (!tree) return tree
|
|
67
|
+
return { ...tree, root: expandGroup(tree.root, timeZone) } as T
|
|
68
|
+
}
|