@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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/modules/customer_accounts/api/admin/roles.js +25 -2
- package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users.js +24 -7
- package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js +77 -15
- package/dist/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +12 -1
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/data/validators.js +2 -1
- package/dist/modules/customer_accounts/data/validators.js.map +2 -2
- package/dist/modules/customer_accounts/lib/adminOrganizationScope.js +46 -0
- package/dist/modules/customer_accounts/lib/adminOrganizationScope.js.map +7 -0
- package/dist/modules/customers/api/customer-dictionary-entries/route.js +86 -0
- package/dist/modules/customers/api/customer-dictionary-entries/route.js.map +7 -0
- package/dist/modules/customers/api/dictionaries/[kind]/route.js +29 -7
- package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
- package/dist/modules/customers/cli.js +28 -110
- package/dist/modules/customers/cli.js.map +3 -3
- package/dist/modules/customers/components/DictionarySettings.js +1 -1
- package/dist/modules/customers/components/DictionarySettings.js.map +1 -1
- package/dist/modules/customers/components/detail/ManageTagsDialog.js +1 -1
- package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/TaskDialog.js +14 -1
- package/dist/modules/customers/components/detail/TaskDialog.js.map +2 -2
- package/dist/modules/customers/components/detail/TaskForm.js +1 -16
- package/dist/modules/customers/components/detail/TaskForm.js.map +2 -2
- package/dist/modules/customers/components/detail/TasksSection.js +38 -10
- package/dist/modules/customers/components/detail/TasksSection.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +12 -5
- package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +2 -2
- package/dist/modules/customers/components/detail/hooks/useInteractions.js +3 -13
- package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
- package/dist/modules/customers/lib/dictionaryDefaults.js +134 -0
- package/dist/modules/customers/lib/dictionaryDefaults.js.map +7 -0
- package/dist/modules/customers/lib/dictionaryLabels.js +59 -0
- package/dist/modules/customers/lib/dictionaryLabels.js.map +7 -0
- package/dist/modules/customers/lib/interactionCompatibility.js +1 -0
- package/dist/modules/customers/lib/interactionCompatibility.js.map +2 -2
- package/dist/modules/customers/translations.js +9 -0
- package/dist/modules/customers/translations.js.map +7 -0
- package/dist/modules/eudr/index.js +13 -0
- package/dist/modules/eudr/index.js.map +2 -2
- package/dist/modules/staff/api/timesheets/access-requests/route.js +11 -5
- package/dist/modules/staff/api/timesheets/access-requests/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-projects/route.js +19 -12
- package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +21 -12
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +14 -9
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js +31 -10
- package/dist/modules/staff/lib/time-tracking-ui/NoProjectAccess.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/projectAccessScope.js +64 -0
- package/dist/modules/staff/lib/time-tracking-ui/projectAccessScope.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/projectAccessScopeHeaders.js +13 -0
- package/dist/modules/staff/lib/time-tracking-ui/projectAccessScopeHeaders.js.map +7 -0
- package/dist/modules/sync_excel/index.js +11 -1
- package/dist/modules/sync_excel/index.js.map +2 -2
- package/dist/modules/translations/di.js +2 -0
- package/dist/modules/translations/di.js.map +2 -2
- package/package.json +7 -7
- package/src/modules/customer_accounts/api/admin/roles.ts +26 -2
- package/src/modules/customer_accounts/api/admin/users.ts +26 -7
- package/src/modules/customer_accounts/backend/customer_accounts/users/PortalUsersPageClient.tsx +96 -13
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +9 -1
- package/src/modules/customer_accounts/data/validators.ts +1 -0
- package/src/modules/customer_accounts/i18n/de.json +10 -0
- package/src/modules/customer_accounts/i18n/en.json +10 -0
- package/src/modules/customer_accounts/i18n/es.json +10 -0
- package/src/modules/customer_accounts/i18n/ko.json +10 -0
- package/src/modules/customer_accounts/i18n/pl.json +10 -0
- package/src/modules/customer_accounts/lib/adminOrganizationScope.ts +71 -0
- package/src/modules/customers/api/customer-dictionary-entries/route.ts +82 -0
- package/src/modules/customers/api/dictionaries/[kind]/route.ts +29 -6
- package/src/modules/customers/cli.ts +23 -124
- package/src/modules/customers/components/DictionarySettings.tsx +1 -1
- package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1 -1
- package/src/modules/customers/components/detail/TaskDialog.tsx +15 -1
- package/src/modules/customers/components/detail/TaskForm.tsx +1 -17
- package/src/modules/customers/components/detail/TasksSection.tsx +44 -14
- package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +14 -8
- package/src/modules/customers/components/detail/hooks/useInteractions.ts +3 -4
- package/src/modules/customers/i18n/de.json +81 -0
- package/src/modules/customers/i18n/en.json +81 -0
- package/src/modules/customers/i18n/es.json +81 -0
- package/src/modules/customers/i18n/ko.json +81 -0
- package/src/modules/customers/i18n/pl.json +81 -0
- package/src/modules/customers/lib/dictionaryDefaults.ts +137 -0
- package/src/modules/customers/lib/dictionaryLabels.ts +73 -0
- package/src/modules/customers/lib/interactionCompatibility.ts +1 -0
- package/src/modules/customers/translations.ts +5 -0
- package/src/modules/eudr/index.ts +13 -0
- package/src/modules/staff/api/timesheets/access-requests/route.ts +13 -14
- package/src/modules/staff/api/timesheets/time-projects/route.ts +22 -13
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +25 -14
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +14 -13
- package/src/modules/staff/lib/time-tracking-ui/NoProjectAccess.tsx +30 -8
- package/src/modules/staff/lib/time-tracking-ui/projectAccessScope.ts +102 -0
- package/src/modules/staff/lib/time-tracking-ui/projectAccessScopeHeaders.ts +15 -0
- package/src/modules/sync_excel/index.ts +10 -0
- 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)
|