@open-mercato/core 0.10.1-develop.7836.1.0ef0f453c6 → 0.10.1-develop.7841.1.af87ac614d

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.
Files changed (102) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/customer_accounts/api/admin/roles.js +25 -2
  3. package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
  4. package/dist/modules/customer_accounts/api/admin/users.js +24 -7
  5. package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
  6. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +77 -15
  7. package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
  8. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +12 -1
  9. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  10. package/dist/modules/customer_accounts/data/validators.js +2 -1
  11. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  12. package/dist/modules/customer_accounts/lib/adminOrganizationScope.js +46 -0
  13. package/dist/modules/customer_accounts/lib/adminOrganizationScope.js.map +7 -0
  14. package/dist/modules/customers/api/customer-dictionary-entries/route.js +86 -0
  15. package/dist/modules/customers/api/customer-dictionary-entries/route.js.map +7 -0
  16. package/dist/modules/customers/api/dictionaries/[kind]/route.js +29 -7
  17. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  18. package/dist/modules/customers/cli.js +28 -110
  19. package/dist/modules/customers/cli.js.map +3 -3
  20. package/dist/modules/customers/components/DictionarySettings.js +1 -1
  21. package/dist/modules/customers/components/DictionarySettings.js.map +1 -1
  22. package/dist/modules/customers/components/detail/ManageTagsDialog.js +1 -1
  23. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
  24. package/dist/modules/customers/components/detail/TaskDialog.js +14 -1
  25. package/dist/modules/customers/components/detail/TaskDialog.js.map +2 -2
  26. package/dist/modules/customers/components/detail/TaskForm.js +1 -16
  27. package/dist/modules/customers/components/detail/TaskForm.js.map +2 -2
  28. package/dist/modules/customers/components/detail/TasksSection.js +38 -10
  29. package/dist/modules/customers/components/detail/TasksSection.js.map +2 -2
  30. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +12 -5
  31. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +2 -2
  32. package/dist/modules/customers/components/detail/hooks/useInteractions.js +3 -13
  33. package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
  34. package/dist/modules/customers/lib/dictionaryDefaults.js +134 -0
  35. package/dist/modules/customers/lib/dictionaryDefaults.js.map +7 -0
  36. package/dist/modules/customers/lib/dictionaryLabels.js +59 -0
  37. package/dist/modules/customers/lib/dictionaryLabels.js.map +7 -0
  38. package/dist/modules/customers/lib/interactionCompatibility.js +1 -0
  39. package/dist/modules/customers/lib/interactionCompatibility.js.map +2 -2
  40. package/dist/modules/customers/translations.js +9 -0
  41. package/dist/modules/customers/translations.js.map +7 -0
  42. package/dist/modules/eudr/index.js +13 -0
  43. package/dist/modules/eudr/index.js.map +2 -2
  44. package/dist/modules/staff/api/timesheets/access-requests/route.js +11 -5
  45. package/dist/modules/staff/api/timesheets/access-requests/route.js.map +2 -2
  46. package/dist/modules/staff/api/timesheets/time-projects/route.js +19 -12
  47. package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
  48. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +21 -12
  49. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +2 -2
  50. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +14 -9
  51. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
  52. package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js +31 -10
  53. package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js.map +2 -2
  54. package/dist/modules/staff/lib/time-tracking-ui/projectAccessScope.js +64 -0
  55. package/dist/modules/staff/lib/time-tracking-ui/projectAccessScope.js.map +7 -0
  56. package/dist/modules/staff/lib/time-tracking-ui/projectAccessScopeHeaders.js +13 -0
  57. package/dist/modules/staff/lib/time-tracking-ui/projectAccessScopeHeaders.js.map +7 -0
  58. package/dist/modules/sync_excel/index.js +11 -1
  59. package/dist/modules/sync_excel/index.js.map +2 -2
  60. package/dist/modules/translations/di.js +2 -0
  61. package/dist/modules/translations/di.js.map +2 -2
  62. package/package.json +7 -7
  63. package/src/modules/customer_accounts/api/admin/roles.ts +26 -2
  64. package/src/modules/customer_accounts/api/admin/users.ts +26 -7
  65. package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +96 -13
  66. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +9 -1
  67. package/src/modules/customer_accounts/data/validators.ts +1 -0
  68. package/src/modules/customer_accounts/i18n/de.json +10 -0
  69. package/src/modules/customer_accounts/i18n/en.json +10 -0
  70. package/src/modules/customer_accounts/i18n/es.json +10 -0
  71. package/src/modules/customer_accounts/i18n/ko.json +10 -0
  72. package/src/modules/customer_accounts/i18n/pl.json +10 -0
  73. package/src/modules/customer_accounts/lib/adminOrganizationScope.ts +71 -0
  74. package/src/modules/customers/api/customer-dictionary-entries/route.ts +82 -0
  75. package/src/modules/customers/api/dictionaries/[kind]/route.ts +29 -6
  76. package/src/modules/customers/cli.ts +23 -124
  77. package/src/modules/customers/components/DictionarySettings.tsx +1 -1
  78. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1 -1
  79. package/src/modules/customers/components/detail/TaskDialog.tsx +15 -1
  80. package/src/modules/customers/components/detail/TaskForm.tsx +1 -17
  81. package/src/modules/customers/components/detail/TasksSection.tsx +44 -14
  82. package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +14 -8
  83. package/src/modules/customers/components/detail/hooks/useInteractions.ts +3 -4
  84. package/src/modules/customers/i18n/de.json +81 -0
  85. package/src/modules/customers/i18n/en.json +81 -0
  86. package/src/modules/customers/i18n/es.json +81 -0
  87. package/src/modules/customers/i18n/ko.json +81 -0
  88. package/src/modules/customers/i18n/pl.json +81 -0
  89. package/src/modules/customers/lib/dictionaryDefaults.ts +137 -0
  90. package/src/modules/customers/lib/dictionaryLabels.ts +73 -0
  91. package/src/modules/customers/lib/interactionCompatibility.ts +1 -0
  92. package/src/modules/customers/translations.ts +5 -0
  93. package/src/modules/eudr/index.ts +13 -0
  94. package/src/modules/staff/api/timesheets/access-requests/route.ts +13 -14
  95. package/src/modules/staff/api/timesheets/time-projects/route.ts +22 -13
  96. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +25 -14
  97. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +14 -13
  98. package/src/modules/staff/lib/time-tracking-ui/NoProjectAccess.tsx +30 -8
  99. package/src/modules/staff/lib/time-tracking-ui/projectAccessScope.ts +102 -0
  100. package/src/modules/staff/lib/time-tracking-ui/projectAccessScopeHeaders.ts +15 -0
  101. package/src/modules/sync_excel/index.ts +10 -0
  102. package/src/modules/translations/di.ts +2 -0
@@ -0,0 +1,102 @@
1
+ "use client"
2
+
3
+ import * as React from 'react'
4
+ import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
5
+ import {
6
+ parseSelectedOrganizationCookie,
7
+ parseSelectedTenantCookie,
8
+ } from '@open-mercato/core/modules/directory/utils/scopeCookies'
9
+ import type { ResolvedProjectAccessScope } from './projectAccessScopeHeaders'
10
+
11
+ export type ProjectAccessScope = {
12
+ projectId: string | null
13
+ tenantId: string | null
14
+ organizationId: string | null
15
+ }
16
+
17
+ export type ProjectAccessScopeState = {
18
+ /** Stable while the scope stays the same; changes when the project, tenant or organization changes. */
19
+ scopeKey: string
20
+ /** Reads the scope cookies again, so it also catches a change that has not been rendered yet. */
21
+ isCurrentScope: () => boolean
22
+ resolvedScope: ResolvedProjectAccessScope | null
23
+ resolveScope: (scope: ResolvedProjectAccessScope | null) => void
24
+ }
25
+
26
+ type ProjectAccessScopeBinding = {
27
+ scope: ProjectAccessScope
28
+ generation: number
29
+ resolvedScope: ResolvedProjectAccessScope | null
30
+ }
31
+
32
+ export function readProjectAccessScope(timeProjectId?: string | null): ProjectAccessScope {
33
+ const cookieHeader = typeof document === 'undefined' ? null : document.cookie
34
+ return {
35
+ projectId: timeProjectId ?? null,
36
+ tenantId: parseSelectedTenantCookie(cookieHeader),
37
+ organizationId: parseSelectedOrganizationCookie(cookieHeader),
38
+ }
39
+ }
40
+
41
+ export function bindProjectAccessScope(
42
+ bound: ProjectAccessScope,
43
+ current: ProjectAccessScope,
44
+ resolvedScope?: ResolvedProjectAccessScope | null,
45
+ ): ProjectAccessScope | null {
46
+ const continues = (boundValue: string | null, currentValue: string | null, resolvedValue?: string) =>
47
+ boundValue === currentValue || (boundValue === null && currentValue === resolvedValue)
48
+ if (bound.projectId !== current.projectId) return null
49
+ if (!continues(bound.tenantId, current.tenantId, resolvedScope?.tenantId)) return null
50
+ if (!continues(bound.organizationId, current.organizationId, resolvedScope?.organizationId)) return null
51
+ return current
52
+ }
53
+
54
+ function isSameProjectAccessScope(left: ProjectAccessScope, right: ProjectAccessScope): boolean {
55
+ return left.projectId === right.projectId
56
+ && left.tenantId === right.tenantId
57
+ && left.organizationId === right.organizationId
58
+ }
59
+
60
+ function rebindProjectAccessScope(
61
+ binding: ProjectAccessScopeBinding,
62
+ current: ProjectAccessScope,
63
+ ): ProjectAccessScopeBinding {
64
+ const continued = bindProjectAccessScope(binding.scope, current, binding.resolvedScope)
65
+ if (!continued) return { scope: current, generation: binding.generation + 1, resolvedScope: null }
66
+ if (isSameProjectAccessScope(continued, binding.scope)) return binding
67
+ return { ...binding, scope: continued }
68
+ }
69
+
70
+ export function useProjectAccessScope(
71
+ timeProjectId?: string | null,
72
+ initialResolvedScope?: ResolvedProjectAccessScope | null,
73
+ ): ProjectAccessScopeState {
74
+ useOrganizationScopeVersion()
75
+ const current = readProjectAccessScope(timeProjectId)
76
+ const [binding, setBinding] = React.useState<ProjectAccessScopeBinding>(() => ({
77
+ scope: current,
78
+ generation: 0,
79
+ resolvedScope: initialResolvedScope ?? null,
80
+ }))
81
+ const nextBinding = rebindProjectAccessScope(binding, current)
82
+ if (nextBinding !== binding) setBinding(nextBinding)
83
+ const boundScope = React.useRef(nextBinding)
84
+ boundScope.current = nextBinding
85
+ const generation = nextBinding.generation
86
+ const isCurrentScope = React.useCallback(() => {
87
+ const active = boundScope.current
88
+ return active.generation === generation
89
+ && bindProjectAccessScope(active.scope, readProjectAccessScope(timeProjectId), active.resolvedScope) !== null
90
+ }, [generation, timeProjectId])
91
+ const resolveScope = React.useCallback((resolvedScope: ResolvedProjectAccessScope | null) => {
92
+ setBinding((previous) => {
93
+ if (previous.generation !== generation) return previous
94
+ if (!bindProjectAccessScope(previous.scope, readProjectAccessScope(timeProjectId), resolvedScope)) return previous
95
+ const changed = previous.resolvedScope !== null && resolvedScope !== null
96
+ && (previous.resolvedScope.tenantId !== resolvedScope.tenantId
97
+ || previous.resolvedScope.organizationId !== resolvedScope.organizationId)
98
+ return { ...previous, resolvedScope, generation: previous.generation + (changed ? 1 : 0) }
99
+ })
100
+ }, [generation, timeProjectId])
101
+ return { scopeKey: String(generation), isCurrentScope, resolvedScope: nextBinding.resolvedScope, resolveScope }
102
+ }
@@ -0,0 +1,15 @@
1
+ export const PROJECT_SCOPE_TENANT_HEADER = 'x-om-project-scope-tenant-id'
2
+ export const PROJECT_SCOPE_ORGANIZATION_HEADER = 'x-om-project-scope-organization-id'
3
+
4
+ export type ResolvedProjectAccessScope = {
5
+ tenantId: string
6
+ organizationId: string
7
+ }
8
+
9
+ export function readResolvedProjectAccessScope(
10
+ response: { headers?: Pick<Headers, 'get'> },
11
+ ): ResolvedProjectAccessScope | null {
12
+ const tenantId = response.headers?.get(PROJECT_SCOPE_TENANT_HEADER)
13
+ const organizationId = response.headers?.get(PROJECT_SCOPE_ORGANIZATION_HEADER)
14
+ return tenantId && organizationId ? { tenantId, organizationId } : null
15
+ }
@@ -2,6 +2,16 @@ export const metadata = {
2
2
  id: 'sync_excel',
3
3
  title: 'Excel / CSV Import',
4
4
  description: 'File-upload-based CSV import foundation built on top of the data sync hub.',
5
+ /**
6
+ * `customers` is a HARD dependency: `lib/adapters/customers.ts` reads `E.customers.*` at module scope.
7
+ *
8
+ * `E` only carries a key for an ENABLED module, so with `customers` switched off that read is
9
+ * `undefined.customer_entity` and it throws while the adapter is being imported — not inside a request, where
10
+ * it could be traced. Declaring it has the generator refuse the combination before anybody starts the app.
11
+ *
12
+ * `data_sync` is the hub this is built on, named in the description and now in the manifest too.
13
+ */
14
+ requires: ['customers', 'data_sync'],
5
15
  }
6
16
 
7
17
  export default metadata
@@ -2,6 +2,7 @@ import { registerTranslatableFields } from '@open-mercato/shared/lib/localizatio
2
2
  import { registerTranslationOverlayPlugin } from '@open-mercato/shared/lib/localization/overlay-plugin'
3
3
  import { registerSupportedLocalesResolver } from '@open-mercato/shared/lib/i18n/locale-registry'
4
4
  import { translatableFields as catalogFields } from '../catalog/translations'
5
+ import { translatableFields as customerFields } from '../customers/translations'
5
6
  import { translatableFields as dictionaryFields } from '../dictionaries/translations'
6
7
  import { translatableFields as entitiesFields } from '../entities/translations'
7
8
  import { translatableFields as resourcesFields } from '../resources/translations'
@@ -19,6 +20,7 @@ registerSupportedLocalesResolver(resolveTenantSupportedLocales)
19
20
 
20
21
  export function register() {
21
22
  registerTranslatableFields(catalogFields)
23
+ registerTranslatableFields(customerFields)
22
24
  registerTranslatableFields(dictionaryFields)
23
25
  registerTranslatableFields(entitiesFields)
24
26
  registerTranslatableFields(resourcesFields)