@open-mercato/core 0.6.6-develop.6551.1.1511bfa890 → 0.6.6
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 +2 -2
- package/dist/generated/entities.ids.generated.js +0 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +0 -12
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/api_keys/api/keys/route.js +13 -30
- package/dist/modules/api_keys/api/keys/route.js.map +2 -2
- package/dist/modules/api_keys/cli.js +1 -2
- package/dist/modules/api_keys/cli.js.map +2 -2
- package/dist/modules/attachments/api/file/[id]/route.js +7 -9
- package/dist/modules/attachments/api/file/[id]/route.js.map +2 -2
- package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js +7 -9
- package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +17 -21
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentContentPreview.js +35 -6
- package/dist/modules/attachments/components/AttachmentContentPreview.js.map +2 -2
- package/dist/modules/audit_logs/backend/audit-logs/page.js +24 -14
- package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +2 -6
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/cli.js +2 -3
- package/dist/modules/auth/cli.js.map +2 -2
- package/dist/modules/configs/lib/upgrade-actions.js +0 -22
- package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id]/acl.js +0 -1
- package/dist/modules/customer_accounts/api/admin/roles/[id]/acl.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/roles/[id].js +3 -17
- package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js +1 -6
- package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/users-invite.js +1 -6
- package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerInvitationService.js +0 -1
- package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
- package/dist/modules/customer_accounts/services/customerRbacService.js +1 -6
- package/dist/modules/customer_accounts/services/customerRbacService.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection-table.js +2 -0
- package/dist/modules/customer_accounts/widgets/injection-table.js.map +2 -2
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +1 -7
- package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/ViewTabsRow.js +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/components/ViewTabsRow.js.map +2 -2
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js +43 -37
- package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/DealDetailTabs.js +35 -23
- package/dist/modules/customers/components/detail/DealDetailTabs.js.map +2 -2
- package/dist/modules/customers/components/detail/DetailTabsLayout.js +21 -6
- package/dist/modules/customers/components/detail/DetailTabsLayout.js.map +2 -2
- package/dist/modules/customers/components/detail/MobilePersonDetail.js +32 -26
- package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +2 -2
- package/dist/modules/customers/components/detail/PersonDetailTabs.js +39 -29
- package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
- package/dist/modules/dashboards/api/roles/widgets/route.js +3 -22
- package/dist/modules/dashboards/api/roles/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/api/users/widgets/route.js +3 -22
- package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/cli.js +3 -4
- package/dist/modules/dashboards/cli.js.map +2 -2
- package/dist/modules/dashboards/lib/widgetAssignmentScope.js +1 -9
- package/dist/modules/dashboards/lib/widgetAssignmentScope.js.map +2 -2
- package/dist/modules/dictionaries/commands/entries.js +14 -7
- package/dist/modules/dictionaries/commands/entries.js.map +2 -2
- package/dist/modules/dictionaries/commands/entry-operations.js +16 -7
- package/dist/modules/dictionaries/commands/entry-operations.js.map +2 -2
- package/dist/modules/dictionaries/commands/factory.js +3 -9
- package/dist/modules/dictionaries/commands/factory.js.map +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js +41 -56
- package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
- package/dist/modules/directory/utils/organizationScope.js +3 -10
- package/dist/modules/directory/utils/organizationScope.js.map +2 -2
- package/dist/modules/entities/api/records.js +4 -5
- package/dist/modules/entities/api/records.js.map +2 -2
- package/dist/modules/entities/backend/entities/system/[entityId]/page.meta.js +0 -1
- package/dist/modules/entities/backend/entities/system/[entityId]/page.meta.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js +49 -49
- package/dist/modules/entities/backend/entities/user/[entityId]/page.js.map +2 -2
- package/dist/modules/entities/backend/entities/user/[entityId]/page.meta.js +0 -1
- package/dist/modules/entities/backend/entities/user/[entityId]/page.meta.js.map +2 -2
- package/dist/modules/entities/cli.js +1 -2
- package/dist/modules/entities/cli.js.map +2 -2
- package/dist/modules/feature_toggles/api/check/boolean/route.js +14 -0
- package/dist/modules/feature_toggles/api/check/boolean/route.js.map +2 -2
- package/dist/modules/feature_toggles/defaults.json +0 -8
- package/dist/modules/integrations/backend/integrations/[id]/page.js +80 -9
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/payment_gateways/data/entities.js +0 -45
- package/dist/modules/payment_gateways/data/entities.js.map +2 -2
- package/dist/modules/payment_gateways/lib/gateway-service.js +38 -173
- package/dist/modules/payment_gateways/lib/gateway-service.js.map +3 -3
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +14 -16
- package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +30 -18
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/query_index/api/status.js +8 -2
- package/dist/modules/query_index/api/status.js.map +2 -2
- package/dist/modules/resources/backend/resources/resources/[id]/page.js +24 -24
- package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/create/page.js +0 -6
- package/dist/modules/sales/backend/sales/channels/create/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/create/page.meta.js +0 -2
- package/dist/modules/sales/backend/sales/channels/create/page.meta.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -6
- package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.meta.js +0 -2
- package/dist/modules/sales/backend/sales/channels/offers/page.meta.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.js +0 -6
- package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
- package/dist/modules/sales/backend/sales/channels/page.meta.js +0 -2
- package/dist/modules/sales/backend/sales/channels/page.meta.js.map +2 -2
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +4 -6
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +0 -44
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +27 -2
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +2 -6
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/ItemsSection.js +0 -1
- package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
- package/dist/modules/sales/components/documents/LineItemDialog.js +0 -9
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +3 -51
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js +8 -10
- package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
- package/dist/modules/sales/components/documents/ShipmentDialog.js +38 -59
- package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
- package/dist/modules/sales/lib/shipments/snapshots.js +1 -27
- package/dist/modules/sales/lib/shipments/snapshots.js.map +2 -2
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js +25 -22
- package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +14 -12
- package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.js +29 -10
- package/dist/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.js.map +2 -2
- package/dist/modules/sync_excel/lib/adapters/customers.js +20 -19
- package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
- package/dist/modules/sync_excel/lib/parser.js +0 -185
- package/dist/modules/sync_excel/lib/parser.js.map +2 -2
- package/dist/modules/sync_excel/lib/upload-storage.js +1 -20
- package/dist/modules/sync_excel/lib/upload-storage.js.map +2 -2
- package/dist/modules/workflows/frontend/checkout-demo/page.js +8 -1
- package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
- package/dist/modules/workflows/lib/activity-executor.js +1 -1
- package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
- package/dist/modules/workflows/lib/find-definition.js +18 -2
- package/dist/modules/workflows/lib/find-definition.js.map +2 -2
- package/dist/modules/workflows/lib/signal-handler.js +3 -2
- package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
- package/dist/modules/workflows/lib/step-handler.js +4 -8
- package/dist/modules/workflows/lib/step-handler.js.map +2 -2
- package/dist/modules/workflows/lib/task-handler.js +3 -5
- package/dist/modules/workflows/lib/task-handler.js.map +2 -2
- package/dist/modules/workflows/lib/timer-handler.js +2 -1
- package/dist/modules/workflows/lib/timer-handler.js.map +2 -2
- package/dist/modules/workflows/lib/transition-handler.js +5 -13
- package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
- package/dist/modules/workflows/lib/workflow-executor.js +11 -9
- package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
- package/dist/modules/workflows/migrations/Migration20260715120000.js +68 -0
- package/dist/modules/workflows/migrations/Migration20260715120000.js.map +7 -0
- package/dist/modules/workflows/migrations/Migration20260716120000.js +24 -0
- package/dist/modules/workflows/migrations/Migration20260716120000.js.map +7 -0
- package/dist/modules/workflows/workflows.js +2 -0
- package/dist/modules/workflows/workflows.js.map +2 -2
- package/generated/entities.ids.generated.ts +0 -1
- package/generated/entity-fields-registry.ts +0 -12
- package/package.json +8 -9
- package/src/modules/api_keys/api/keys/route.ts +13 -36
- package/src/modules/api_keys/cli.ts +3 -2
- package/src/modules/attachments/api/file/[id]/route.ts +7 -11
- package/src/modules/attachments/api/image/[id]/[[...slug]]/route.ts +7 -11
- package/src/modules/attachments/api/route.ts +21 -26
- package/src/modules/attachments/components/AttachmentContentPreview.tsx +44 -9
- package/src/modules/audit_logs/backend/audit-logs/page.tsx +22 -12
- package/src/modules/auth/api/users/route.ts +2 -11
- package/src/modules/auth/cli.ts +2 -3
- package/src/modules/configs/i18n/de.json +1 -5
- package/src/modules/configs/i18n/en.json +1 -5
- package/src/modules/configs/i18n/es.json +1 -5
- package/src/modules/configs/i18n/pl.json +1 -5
- package/src/modules/configs/lib/upgrade-actions.ts +0 -24
- package/src/modules/customer_accounts/AGENTS.md +6 -8
- package/src/modules/customer_accounts/api/admin/roles/[id]/acl.ts +0 -1
- package/src/modules/customer_accounts/api/admin/roles/[id].ts +3 -17
- package/src/modules/customer_accounts/api/portal/users/[id]/roles.ts +1 -6
- package/src/modules/customer_accounts/api/portal/users-invite.ts +1 -6
- package/src/modules/customer_accounts/services/customerInvitationService.ts +0 -1
- package/src/modules/customer_accounts/services/customerRbacService.ts +2 -9
- package/src/modules/customer_accounts/widgets/injection-table.ts +2 -0
- package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +1 -11
- package/src/modules/customers/backend/customers/deals/pipeline/components/ViewTabsRow.tsx +2 -6
- package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +55 -39
- package/src/modules/customers/components/detail/DealDetailTabs.tsx +49 -24
- package/src/modules/customers/components/detail/DetailTabsLayout.tsx +24 -13
- package/src/modules/customers/components/detail/MobilePersonDetail.tsx +31 -25
- package/src/modules/customers/components/detail/PersonDetailTabs.tsx +50 -29
- package/src/modules/dashboards/api/roles/widgets/route.ts +3 -22
- package/src/modules/dashboards/api/users/widgets/route.ts +3 -22
- package/src/modules/dashboards/cli.ts +9 -4
- package/src/modules/dashboards/lib/widgetAssignmentScope.ts +0 -18
- package/src/modules/dictionaries/commands/entries.ts +16 -7
- package/src/modules/dictionaries/commands/entry-operations.ts +18 -8
- package/src/modules/dictionaries/commands/factory.ts +2 -8
- package/src/modules/dictionaries/fields/dictionary.tsx +32 -55
- package/src/modules/dictionaries/i18n/de.json +0 -2
- package/src/modules/dictionaries/i18n/en.json +0 -2
- package/src/modules/dictionaries/i18n/es.json +0 -2
- package/src/modules/dictionaries/i18n/pl.json +0 -2
- package/src/modules/directory/utils/organizationScope.ts +2 -36
- package/src/modules/entities/api/records.ts +7 -5
- package/src/modules/entities/backend/entities/system/[entityId]/page.meta.ts +0 -1
- package/src/modules/entities/backend/entities/user/[entityId]/page.meta.ts +0 -1
- package/src/modules/entities/backend/entities/user/[entityId]/page.tsx +49 -51
- package/src/modules/entities/cli.ts +1 -2
- package/src/modules/entities/i18n/de.json +0 -34
- package/src/modules/entities/i18n/en.json +0 -34
- package/src/modules/entities/i18n/es.json +0 -34
- package/src/modules/entities/i18n/pl.json +0 -34
- package/src/modules/feature_toggles/api/check/boolean/route.ts +15 -0
- package/src/modules/feature_toggles/defaults.json +0 -8
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +59 -16
- package/src/modules/payment_gateways/data/entities.ts +0 -39
- package/src/modules/payment_gateways/lib/gateway-service.ts +40 -211
- package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +0 -236
- package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +20 -14
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -16
- package/src/modules/query_index/api/status.ts +8 -2
- package/src/modules/resources/backend/resources/resources/[id]/page.tsx +37 -27
- package/src/modules/sales/backend/sales/channels/create/page.meta.ts +0 -3
- package/src/modules/sales/backend/sales/channels/create/page.tsx +0 -7
- package/src/modules/sales/backend/sales/channels/offers/page.meta.ts +0 -3
- package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -7
- package/src/modules/sales/backend/sales/channels/page.meta.ts +0 -4
- package/src/modules/sales/backend/sales/channels/page.tsx +0 -7
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +5 -7
- package/src/modules/sales/commands/documents.ts +0 -65
- package/src/modules/sales/commands/returns.ts +32 -2
- package/src/modules/sales/components/documents/AddressesSection.tsx +2 -6
- package/src/modules/sales/components/documents/ItemsSection.tsx +0 -5
- package/src/modules/sales/components/documents/LineItemDialog.tsx +0 -10
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +3 -53
- package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +8 -10
- package/src/modules/sales/components/documents/ShipmentDialog.tsx +40 -65
- package/src/modules/sales/i18n/de.json +0 -5
- package/src/modules/sales/i18n/en.json +0 -5
- package/src/modules/sales/i18n/es.json +0 -5
- package/src/modules/sales/i18n/pl.json +0 -5
- package/src/modules/sales/lib/shipments/snapshots.ts +0 -30
- package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +34 -25
- package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +17 -11
- package/src/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.tsx +28 -11
- package/src/modules/sync_excel/lib/adapters/customers.ts +22 -20
- package/src/modules/sync_excel/lib/parser.ts +0 -245
- package/src/modules/sync_excel/lib/upload-storage.ts +1 -23
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +12 -1
- package/src/modules/workflows/lib/activity-executor.ts +22 -2
- package/src/modules/workflows/lib/find-definition.ts +53 -1
- package/src/modules/workflows/lib/signal-handler.ts +5 -4
- package/src/modules/workflows/lib/step-handler.ts +4 -8
- package/src/modules/workflows/lib/task-handler.ts +2 -4
- package/src/modules/workflows/lib/timer-handler.ts +3 -2
- package/src/modules/workflows/lib/transition-handler.ts +5 -13
- package/src/modules/workflows/lib/workflow-executor.ts +11 -8
- package/src/modules/workflows/migrations/Migration20260715120000.ts +114 -0
- package/src/modules/workflows/migrations/Migration20260716120000.ts +57 -0
- package/src/modules/workflows/workflows.ts +2 -0
- package/dist/generated/entities/gateway_session_initialization/index.js +0 -23
- package/dist/generated/entities/gateway_session_initialization/index.js.map +0 -7
- package/dist/modules/attachments/lib/reconcileOrganization.js +0 -110
- package/dist/modules/attachments/lib/reconcileOrganization.js.map +0 -7
- package/dist/modules/attachments/lib/requestScope.js +0 -10
- package/dist/modules/attachments/lib/requestScope.js.map +0 -7
- package/dist/modules/auth/api/autologin.js +0 -85
- package/dist/modules/auth/api/autologin.js.map +0 -7
- package/dist/modules/auth/lib/autologin.js +0 -19
- package/dist/modules/auth/lib/autologin.js.map +0 -7
- package/dist/modules/customers/components/detail/useDealsAccess.js +0 -16
- package/dist/modules/customers/components/detail/useDealsAccess.js.map +0 -7
- package/dist/modules/payment_gateways/lib/session-idempotency.js +0 -104
- package/dist/modules/payment_gateways/lib/session-idempotency.js.map +0 -7
- package/dist/modules/payment_gateways/migrations/Migration20260709220938_payment_gateways.js +0 -11
- package/dist/modules/payment_gateways/migrations/Migration20260709220938_payment_gateways.js.map +0 -7
- package/dist/modules/sales/components/SalesChannelsDisabledNotice.js +0 -15
- package/dist/modules/sales/components/SalesChannelsDisabledNotice.js.map +0 -7
- package/dist/modules/sales/components/useSalesChannelsEnabled.js +0 -44
- package/dist/modules/sales/components/useSalesChannelsEnabled.js.map +0 -7
- package/dist/modules/sales/lib/salesChannelsToggle.js +0 -18
- package/dist/modules/sales/lib/salesChannelsToggle.js.map +0 -7
- package/dist/modules/sales/lib/salesChannelsToggleId.js +0 -5
- package/dist/modules/sales/lib/salesChannelsToggleId.js.map +0 -7
- package/generated/entities/gateway_session_initialization/index.ts +0 -10
- package/src/modules/attachments/lib/reconcileOrganization.ts +0 -188
- package/src/modules/attachments/lib/requestScope.ts +0 -27
- package/src/modules/auth/api/autologin.ts +0 -100
- package/src/modules/auth/lib/autologin.ts +0 -36
- package/src/modules/customers/components/detail/useDealsAccess.ts +0 -19
- package/src/modules/payment_gateways/lib/session-idempotency.ts +0 -142
- package/src/modules/payment_gateways/migrations/Migration20260709220938_payment_gateways.ts +0 -10
- package/src/modules/sales/components/SalesChannelsDisabledNotice.tsx +0 -21
- package/src/modules/sales/components/useSalesChannelsEnabled.ts +0 -59
- package/src/modules/sales/lib/salesChannelsToggle.ts +0 -26
- package/src/modules/sales/lib/salesChannelsToggleId.ts +0 -1
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { Activity, Building2, History, NotebookPen, Paperclip, Users } from 'lucide-react'
|
|
5
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
5
6
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
6
|
-
import {
|
|
7
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
7
8
|
|
|
8
9
|
export type DealTabId =
|
|
9
10
|
| 'activities'
|
|
@@ -18,7 +19,7 @@ type TabDef = {
|
|
|
18
19
|
id: DealTabId
|
|
19
20
|
label: string
|
|
20
21
|
icon?: React.ReactNode
|
|
21
|
-
|
|
22
|
+
badge?: React.ReactNode
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
type DealDetailTabsProps = {
|
|
@@ -37,9 +38,21 @@ export function resolveLegacyTab(tab: string | null | undefined): DealTabId {
|
|
|
37
38
|
return SUPPORTED_TAB_IDS.has(tab as DealTabId) ? (tab as DealTabId) : 'activities'
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
function
|
|
41
|
-
if (count <= 0) return
|
|
42
|
-
return
|
|
41
|
+
function CountBadge({ count }: { count: number }) {
|
|
42
|
+
if (count <= 0) return null
|
|
43
|
+
return (
|
|
44
|
+
<span className="ml-1.5 rounded-sm bg-muted px-1.5 py-px text-xs font-semibold leading-none text-muted-foreground">
|
|
45
|
+
{count > 999 ? '999+' : count}
|
|
46
|
+
</span>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function NewBadge() {
|
|
51
|
+
return (
|
|
52
|
+
<span className="ml-1.5 rounded-sm bg-muted px-1.5 py-px text-xs font-semibold leading-none text-muted-foreground">
|
|
53
|
+
NEW
|
|
54
|
+
</span>
|
|
55
|
+
)
|
|
43
56
|
}
|
|
44
57
|
|
|
45
58
|
export function DealDetailTabs({
|
|
@@ -63,13 +76,13 @@ export function DealDetailTabs({
|
|
|
63
76
|
id: 'people',
|
|
64
77
|
label: t('customers.deals.detail.tabs.people', 'People'),
|
|
65
78
|
icon: <Users className="size-4" />,
|
|
66
|
-
|
|
79
|
+
badge: <CountBadge count={peopleCount} />,
|
|
67
80
|
},
|
|
68
81
|
{
|
|
69
82
|
id: 'companies',
|
|
70
83
|
label: t('customers.deals.detail.tabs.companies', 'Companies'),
|
|
71
84
|
icon: <Building2 className="size-4" />,
|
|
72
|
-
|
|
85
|
+
badge: <CountBadge count={companiesCount} />,
|
|
73
86
|
},
|
|
74
87
|
{
|
|
75
88
|
id: 'notes',
|
|
@@ -85,7 +98,7 @@ export function DealDetailTabs({
|
|
|
85
98
|
id: 'changelog',
|
|
86
99
|
label: t('customers.deals.detail.tabs.changelog', 'Changelog'),
|
|
87
100
|
icon: <History className="size-4" />,
|
|
88
|
-
|
|
101
|
+
badge: <NewBadge />,
|
|
89
102
|
},
|
|
90
103
|
],
|
|
91
104
|
[companiesCount, peopleCount, t],
|
|
@@ -104,22 +117,34 @@ export function DealDetailTabs({
|
|
|
104
117
|
|
|
105
118
|
return (
|
|
106
119
|
<div>
|
|
107
|
-
<
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
<div className="border-b border-border" role="tablist" aria-label={t('customers.deals.detail.tabs.label', 'Deal detail sections')}>
|
|
121
|
+
<nav className="-mb-px flex gap-7 overflow-x-auto" role="presentation">
|
|
122
|
+
{allTabs.map((tab) => {
|
|
123
|
+
const isActive = activeTab === tab.id
|
|
124
|
+
return (
|
|
125
|
+
<Button
|
|
126
|
+
key={tab.id}
|
|
127
|
+
type="button"
|
|
128
|
+
variant="ghost"
|
|
129
|
+
size="sm"
|
|
130
|
+
role="tab"
|
|
131
|
+
aria-selected={isActive}
|
|
132
|
+
onClick={() => onTabChange(tab.id)}
|
|
133
|
+
className={cn(
|
|
134
|
+
'h-auto shrink-0 rounded-none border-b-2 px-3 py-2.5 hover:bg-transparent',
|
|
135
|
+
isActive
|
|
136
|
+
? 'border-foreground text-foreground font-semibold'
|
|
137
|
+
: 'border-transparent text-muted-foreground hover:text-foreground',
|
|
138
|
+
)}
|
|
139
|
+
>
|
|
140
|
+
{tab.icon ? <span className="mr-1.5">{tab.icon}</span> : null}
|
|
141
|
+
{tab.label}
|
|
142
|
+
{tab.badge}
|
|
143
|
+
</Button>
|
|
144
|
+
)
|
|
145
|
+
})}
|
|
146
|
+
</nav>
|
|
147
|
+
</div>
|
|
123
148
|
|
|
124
149
|
<div className="pt-5" role="tabpanel">
|
|
125
150
|
{children}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import type { SectionAction } from '@open-mercato/ui/backend/detail'
|
|
5
5
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
6
|
-
import { Tabs, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'
|
|
7
6
|
import { cn } from '@open-mercato/shared/lib/utils'
|
|
8
7
|
import { Plus } from 'lucide-react'
|
|
9
8
|
|
|
@@ -47,19 +46,31 @@ export function DetailTabsLayout<TId extends string = string>({
|
|
|
47
46
|
return (
|
|
48
47
|
<div className={cn('space-y-4', className)}>
|
|
49
48
|
<div className={cn('flex flex-wrap items-center justify-between gap-3', headerClassName)}>
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
49
|
+
<nav
|
|
50
|
+
className={cn('flex flex-wrap items-center gap-3 text-sm', navClassName)}
|
|
51
|
+
role="tablist"
|
|
52
|
+
aria-label={navAriaLabel}
|
|
54
53
|
>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
54
|
+
{tabs.map((tab) => (
|
|
55
|
+
<Button
|
|
56
|
+
key={tab.id}
|
|
57
|
+
type="button"
|
|
58
|
+
variant="ghost"
|
|
59
|
+
size="sm"
|
|
60
|
+
role="tab"
|
|
61
|
+
aria-selected={activeTab === tab.id}
|
|
62
|
+
onClick={() => handleTabChange(tab.id)}
|
|
63
|
+
className={cn(
|
|
64
|
+
'h-auto rounded-none border-b-2 px-0 py-1',
|
|
65
|
+
activeTab === tab.id
|
|
66
|
+
? 'border-accent-indigo text-foreground hover:bg-transparent'
|
|
67
|
+
: 'border-transparent text-muted-foreground hover:text-foreground hover:bg-transparent'
|
|
68
|
+
)}
|
|
69
|
+
>
|
|
70
|
+
{tab.label}
|
|
71
|
+
</Button>
|
|
72
|
+
))}
|
|
73
|
+
</nav>
|
|
63
74
|
{sectionAction ? (
|
|
64
75
|
<Button
|
|
65
76
|
type="button"
|
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
import * as React from 'react'
|
|
4
4
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
5
5
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
6
|
-
import {
|
|
6
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
7
|
+
import { Button } from '@open-mercato/ui/primitives/button'
|
|
7
8
|
|
|
8
9
|
export type MobilePersonZone = 'details' | 'activity'
|
|
9
10
|
|
|
@@ -79,30 +80,35 @@ export function MobilePersonDetail({
|
|
|
79
80
|
|
|
80
81
|
return (
|
|
81
82
|
<div className="space-y-4">
|
|
82
|
-
<div
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
83
|
+
<div
|
|
84
|
+
role="tablist"
|
|
85
|
+
aria-label={t(
|
|
86
|
+
'customers.people.mobile.zoneSwitcher.ariaLabel',
|
|
87
|
+
'Zone selector',
|
|
88
|
+
)}
|
|
89
|
+
className="grid grid-cols-2 gap-1 rounded-lg border border-border/70 bg-muted/20 p-1"
|
|
90
|
+
onKeyDown={handleKeyDown}
|
|
91
|
+
>
|
|
92
|
+
{ZONES.map((entry) => {
|
|
93
|
+
const isActive = zone === entry.id
|
|
94
|
+
return (
|
|
95
|
+
<Button
|
|
96
|
+
key={entry.id}
|
|
97
|
+
type="button"
|
|
98
|
+
role="tab"
|
|
99
|
+
aria-selected={isActive}
|
|
100
|
+
aria-controls={`mobile-person-zone-${entry.id}`}
|
|
101
|
+
variant={isActive ? 'default' : 'ghost'}
|
|
102
|
+
className={cn(
|
|
103
|
+
'h-11 rounded-lg text-sm font-semibold',
|
|
104
|
+
isActive ? '' : 'text-muted-foreground',
|
|
105
|
+
)}
|
|
106
|
+
onClick={() => handleZoneChange(entry.id)}
|
|
107
|
+
>
|
|
108
|
+
{t(entry.labelKey, entry.fallback)}
|
|
109
|
+
</Button>
|
|
110
|
+
)
|
|
111
|
+
})}
|
|
106
112
|
</div>
|
|
107
113
|
<div
|
|
108
114
|
id={`mobile-person-zone-${zone}`}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
|
|
3
3
|
import * as React from 'react'
|
|
4
|
+
import { cn } from '@open-mercato/shared/lib/utils'
|
|
4
5
|
import { useT } from '@open-mercato/shared/lib/i18n/context'
|
|
5
6
|
import { Button } from '@open-mercato/ui/primitives/button'
|
|
6
|
-
import { Tabs, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'
|
|
7
7
|
import {
|
|
8
8
|
SquareCheckBig,
|
|
9
9
|
Mail,
|
|
@@ -32,7 +32,7 @@ type TabDef = {
|
|
|
32
32
|
id: PersonTabId
|
|
33
33
|
label: string
|
|
34
34
|
icon?: React.ReactNode
|
|
35
|
-
|
|
35
|
+
badge?: React.ReactNode
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
type PersonDetailTabsProps = {
|
|
@@ -56,9 +56,21 @@ export function resolveLegacyTab(tab: string | null | undefined): PersonTabId {
|
|
|
56
56
|
return SUPPORTED_TAB_IDS.has(tab as PersonTabId) ? (tab as PersonTabId) : 'activities'
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
function
|
|
60
|
-
if (count <= 0) return
|
|
61
|
-
return
|
|
59
|
+
function CountBadge({ count }: { count: number }) {
|
|
60
|
+
if (count <= 0) return null
|
|
61
|
+
return (
|
|
62
|
+
<span className="ml-1 rounded-full bg-muted px-1.5 py-0.5 text-xs font-medium leading-none text-muted-foreground">
|
|
63
|
+
{count > 999 ? '999+' : count}
|
|
64
|
+
</span>
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function NewBadge() {
|
|
69
|
+
return (
|
|
70
|
+
<span className="ml-1.5 rounded bg-foreground px-1.5 py-0.5 text-overline font-semibold leading-none text-background">
|
|
71
|
+
NEW
|
|
72
|
+
</span>
|
|
73
|
+
)
|
|
62
74
|
}
|
|
63
75
|
|
|
64
76
|
export function PersonDetailTabs({
|
|
@@ -82,7 +94,7 @@ export function PersonDetailTabs({
|
|
|
82
94
|
id: 'activities',
|
|
83
95
|
label: t('customers.people.detail.tabs.activities', 'Activities'),
|
|
84
96
|
icon: <SquareCheckBig className="size-4" />,
|
|
85
|
-
|
|
97
|
+
badge: <CountBadge count={activitiesCount} />,
|
|
86
98
|
},
|
|
87
99
|
{
|
|
88
100
|
id: 'emails',
|
|
@@ -93,37 +105,37 @@ export function PersonDetailTabs({
|
|
|
93
105
|
id: 'deals',
|
|
94
106
|
label: t('customers.people.detail.tabs.deals', 'Deals'),
|
|
95
107
|
icon: <Briefcase className="size-4" />,
|
|
96
|
-
|
|
108
|
+
badge: <CountBadge count={dealsCount} />,
|
|
97
109
|
},
|
|
98
110
|
{
|
|
99
111
|
id: 'companies',
|
|
100
112
|
label: t('customers.people.detail.tabs.companies', 'Companies'),
|
|
101
113
|
icon: <Building2 className="size-4" />,
|
|
102
|
-
|
|
114
|
+
badge: <CountBadge count={companiesCount} />,
|
|
103
115
|
},
|
|
104
116
|
{
|
|
105
117
|
id: 'addresses',
|
|
106
118
|
label: t('customers.people.detail.tabs.addresses', 'Addresses'),
|
|
107
119
|
icon: <MapPin className="size-4" />,
|
|
108
|
-
|
|
120
|
+
badge: <CountBadge count={addressesCount} />,
|
|
109
121
|
},
|
|
110
122
|
{
|
|
111
123
|
id: 'tasks',
|
|
112
124
|
label: t('customers.people.detail.tabs.tasks', 'Tasks'),
|
|
113
125
|
icon: <Check className="size-4" />,
|
|
114
|
-
|
|
126
|
+
badge: <CountBadge count={tasksCount} />,
|
|
115
127
|
},
|
|
116
128
|
{
|
|
117
129
|
id: 'changelog',
|
|
118
130
|
label: t('customers.people.detail.tabs.changelog', 'Change log'),
|
|
119
131
|
icon: <History className="size-4" />,
|
|
120
|
-
|
|
132
|
+
badge: <NewBadge />,
|
|
121
133
|
},
|
|
122
134
|
{
|
|
123
135
|
id: 'files',
|
|
124
136
|
label: t('customers.people.detail.tabs.files', 'Files'),
|
|
125
137
|
icon: <Paperclip className="size-4" />,
|
|
126
|
-
|
|
138
|
+
badge: <CountBadge count={filesCount} />,
|
|
127
139
|
},
|
|
128
140
|
],
|
|
129
141
|
[t, activitiesCount, dealsCount, companiesCount, addressesCount, tasksCount, filesCount],
|
|
@@ -143,24 +155,33 @@ export function PersonDetailTabs({
|
|
|
143
155
|
return (
|
|
144
156
|
<div>
|
|
145
157
|
{/* Tab navigation — full width above both zones */}
|
|
146
|
-
<div className="flex items-end justify-between gap-2 border-b">
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
158
|
+
<div className="flex items-end justify-between gap-2 border-b" role="tablist" aria-label={t('customers.people.detail.tabs.label', 'Person detail sections')}>
|
|
159
|
+
<nav className="-mb-px flex flex-1 gap-1 overflow-x-auto px-1">
|
|
160
|
+
{allTabs.map((tab) => {
|
|
161
|
+
const isActive = activeTab === tab.id
|
|
162
|
+
return (
|
|
163
|
+
<Button
|
|
164
|
+
key={tab.id}
|
|
165
|
+
type="button"
|
|
166
|
+
variant="ghost"
|
|
167
|
+
size="sm"
|
|
168
|
+
role="tab"
|
|
169
|
+
aria-selected={isActive}
|
|
170
|
+
onClick={() => onTabChange(tab.id)}
|
|
171
|
+
className={cn(
|
|
172
|
+
'h-auto shrink-0 rounded-none border-b-2 px-3 py-2.5 hover:bg-transparent',
|
|
173
|
+
isActive
|
|
174
|
+
? 'border-foreground text-foreground font-semibold'
|
|
175
|
+
: 'border-transparent text-muted-foreground hover:text-foreground',
|
|
176
|
+
)}
|
|
177
|
+
>
|
|
178
|
+
{tab.icon && <span className="mr-1.5">{tab.icon}</span>}
|
|
159
179
|
{tab.label}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
180
|
+
{tab.badge}
|
|
181
|
+
</Button>
|
|
182
|
+
)
|
|
183
|
+
})}
|
|
184
|
+
</nav>
|
|
164
185
|
{sectionAction ? (
|
|
165
186
|
<Button
|
|
166
187
|
type="button"
|
|
@@ -6,10 +6,7 @@ import { DashboardRoleWidgets } from '@open-mercato/core/modules/dashboards/data
|
|
|
6
6
|
import { Role } from '@open-mercato/core/modules/auth/data/entities'
|
|
7
7
|
import { roleWidgetSettingsSchema } from '@open-mercato/core/modules/dashboards/data/validators'
|
|
8
8
|
import { loadAllWidgets } from '@open-mercato/core/modules/dashboards/lib/widgets'
|
|
9
|
-
import {
|
|
10
|
-
resolveWidgetAssignmentReadScope,
|
|
11
|
-
resolveWidgetAssignmentTargetAccess,
|
|
12
|
-
} from '@open-mercato/core/modules/dashboards/lib/widgetAssignmentScope'
|
|
9
|
+
import { resolveWidgetAssignmentReadScope } from '@open-mercato/core/modules/dashboards/lib/widgetAssignmentScope'
|
|
13
10
|
import { hasFeature } from '@open-mercato/shared/security/features'
|
|
14
11
|
import {
|
|
15
12
|
runCrudMutationGuardAfterSuccess,
|
|
@@ -73,15 +70,7 @@ export async function GET(req: Request) {
|
|
|
73
70
|
})
|
|
74
71
|
|
|
75
72
|
const role = await em.findOne(Role, { id: roleId, deletedAt: null })
|
|
76
|
-
|
|
77
|
-
isSuperAdmin: !!acl.isSuperAdmin,
|
|
78
|
-
scopeTenantId: tenantId,
|
|
79
|
-
target: role,
|
|
80
|
-
})
|
|
81
|
-
if (access === 'forbidden') {
|
|
82
|
-
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
|
83
|
-
}
|
|
84
|
-
if (access === 'not-found') {
|
|
73
|
+
if (!role || (tenantId && role.tenantId !== tenantId)) {
|
|
85
74
|
return NextResponse.json({ error: 'Role not found' }, { status: 404 })
|
|
86
75
|
}
|
|
87
76
|
|
|
@@ -132,15 +121,7 @@ export async function PUT(req: Request) {
|
|
|
132
121
|
const organizationId = auth.orgId ?? null
|
|
133
122
|
|
|
134
123
|
const role = await em.findOne(Role, { id: parsed.data.roleId, deletedAt: null })
|
|
135
|
-
|
|
136
|
-
isSuperAdmin: !!acl.isSuperAdmin,
|
|
137
|
-
scopeTenantId: tenantId,
|
|
138
|
-
target: role,
|
|
139
|
-
})
|
|
140
|
-
if (access === 'forbidden') {
|
|
141
|
-
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
|
142
|
-
}
|
|
143
|
-
if (access === 'not-found') {
|
|
124
|
+
if (!role || (tenantId && role.tenantId !== tenantId)) {
|
|
144
125
|
return NextResponse.json({ error: 'Role not found' }, { status: 404 })
|
|
145
126
|
}
|
|
146
127
|
|
|
@@ -7,10 +7,7 @@ import { User } from '@open-mercato/core/modules/auth/data/entities'
|
|
|
7
7
|
import { userWidgetSettingsSchema } from '@open-mercato/core/modules/dashboards/data/validators'
|
|
8
8
|
import { loadAllWidgets } from '@open-mercato/core/modules/dashboards/lib/widgets'
|
|
9
9
|
import { resolveAllowedWidgetIds } from '@open-mercato/core/modules/dashboards/lib/access'
|
|
10
|
-
import {
|
|
11
|
-
resolveWidgetAssignmentReadScope,
|
|
12
|
-
resolveWidgetAssignmentTargetAccess,
|
|
13
|
-
} from '@open-mercato/core/modules/dashboards/lib/widgetAssignmentScope'
|
|
10
|
+
import { resolveWidgetAssignmentReadScope } from '@open-mercato/core/modules/dashboards/lib/widgetAssignmentScope'
|
|
14
11
|
import { hasFeature } from '@open-mercato/shared/security/features'
|
|
15
12
|
import {
|
|
16
13
|
runCrudMutationGuardAfterSuccess,
|
|
@@ -56,15 +53,7 @@ export async function GET(req: Request) {
|
|
|
56
53
|
})
|
|
57
54
|
|
|
58
55
|
const targetUserForRead = await em.findOne(User, { id: userId, deletedAt: null })
|
|
59
|
-
|
|
60
|
-
isSuperAdmin: !!acl.isSuperAdmin,
|
|
61
|
-
scopeTenantId: tenantId,
|
|
62
|
-
target: targetUserForRead,
|
|
63
|
-
})
|
|
64
|
-
if (readAccess === 'forbidden') {
|
|
65
|
-
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
|
66
|
-
}
|
|
67
|
-
if (readAccess === 'not-found') {
|
|
56
|
+
if (!targetUserForRead || (tenantId && (targetUserForRead.tenantId ?? null) !== tenantId)) {
|
|
68
57
|
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
|
69
58
|
}
|
|
70
59
|
|
|
@@ -132,15 +121,7 @@ export async function PUT(req: Request) {
|
|
|
132
121
|
const organizationId = auth.orgId ?? null
|
|
133
122
|
|
|
134
123
|
const targetUser = await em.findOne(User, { id: parsed.data.userId, deletedAt: null })
|
|
135
|
-
|
|
136
|
-
isSuperAdmin: !!acl.isSuperAdmin,
|
|
137
|
-
scopeTenantId: tenantId,
|
|
138
|
-
target: targetUser,
|
|
139
|
-
})
|
|
140
|
-
if (writeAccess === 'forbidden') {
|
|
141
|
-
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
|
|
142
|
-
}
|
|
143
|
-
if (writeAccess === 'not-found') {
|
|
124
|
+
if (!targetUser || (tenantId && (targetUser.tenantId ?? null) !== tenantId)) {
|
|
144
125
|
return NextResponse.json({ error: 'User not found' }, { status: 404 })
|
|
145
126
|
}
|
|
146
127
|
|
|
@@ -6,7 +6,6 @@ import { Role } from '@open-mercato/core/modules/auth/data/entities'
|
|
|
6
6
|
import { loadAllWidgets } from '@open-mercato/core/modules/dashboards/lib/widgets'
|
|
7
7
|
import { appendWidgetsToRoles, resolveAnalyticsWidgetIds } from '@open-mercato/core/modules/dashboards/lib/role-widgets'
|
|
8
8
|
import { seedAnalyticsData } from './seed/analytics'
|
|
9
|
-
import { parseCommaSeparatedList } from '@open-mercato/shared/lib/string'
|
|
10
9
|
|
|
11
10
|
type Args = Record<string, string>
|
|
12
11
|
|
|
@@ -109,7 +108,10 @@ const seedDefaults: ModuleCli = {
|
|
|
109
108
|
return
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
const roleNames =
|
|
111
|
+
const roleNames = roleCsv
|
|
112
|
+
.split(',')
|
|
113
|
+
.map((name) => name.trim())
|
|
114
|
+
.filter(Boolean)
|
|
113
115
|
|
|
114
116
|
if (!roleNames.length) {
|
|
115
117
|
console.log('No roles provided, nothing to seed.')
|
|
@@ -123,7 +125,7 @@ const seedDefaults: ModuleCli = {
|
|
|
123
125
|
tenantId,
|
|
124
126
|
organizationId,
|
|
125
127
|
roleNames,
|
|
126
|
-
widgetIds: widgetCsv ?
|
|
128
|
+
widgetIds: widgetCsv ? widgetCsv.split(',').map((id) => id.trim()).filter(Boolean) : undefined,
|
|
127
129
|
logger: (message) => console.log(message),
|
|
128
130
|
})
|
|
129
131
|
},
|
|
@@ -141,7 +143,10 @@ const enableAnalyticsWidgets: ModuleCli = {
|
|
|
141
143
|
return
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
const roleNames =
|
|
146
|
+
const roleNames = roleCsv
|
|
147
|
+
.split(',')
|
|
148
|
+
.map((name) => name.trim())
|
|
149
|
+
.filter(Boolean)
|
|
145
150
|
|
|
146
151
|
if (!roleNames.length) {
|
|
147
152
|
console.log('No roles provided, nothing to update.')
|
|
@@ -8,24 +8,6 @@ export type ResolvedAssignmentScope = {
|
|
|
8
8
|
organizationId: string | null
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export type WidgetAssignmentTarget = {
|
|
12
|
-
tenantId?: string | null
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type WidgetAssignmentTargetAccess = 'allowed' | 'forbidden' | 'not-found'
|
|
16
|
-
|
|
17
|
-
export function resolveWidgetAssignmentTargetAccess(params: {
|
|
18
|
-
isSuperAdmin: boolean
|
|
19
|
-
scopeTenantId: string | null
|
|
20
|
-
target: WidgetAssignmentTarget | null | undefined
|
|
21
|
-
}): WidgetAssignmentTargetAccess {
|
|
22
|
-
const { isSuperAdmin, scopeTenantId, target } = params
|
|
23
|
-
if (!isSuperAdmin && !scopeTenantId) return 'forbidden'
|
|
24
|
-
if (!target) return 'not-found'
|
|
25
|
-
if (scopeTenantId && (target.tenantId ?? null) !== scopeTenantId) return 'not-found'
|
|
26
|
-
return 'allowed'
|
|
27
|
-
}
|
|
28
|
-
|
|
29
11
|
export function resolveWidgetAssignmentReadScope(params: {
|
|
30
12
|
auth: AuthScopeInput
|
|
31
13
|
isSuperAdmin: boolean
|
|
@@ -4,13 +4,22 @@ import {
|
|
|
4
4
|
dictionaryEntryCommandCreateSchema,
|
|
5
5
|
dictionaryEntryCommandUpdateSchema,
|
|
6
6
|
} from '@open-mercato/core/modules/dictionaries/data/validators'
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
registerDictionaryEntryCommands,
|
|
10
|
-
} from '@open-mercato/core/modules/dictionaries/commands/factory'
|
|
7
|
+
import { registerDictionaryEntryCommands } from '@open-mercato/core/modules/dictionaries/commands/factory'
|
|
8
|
+
import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
|
|
11
9
|
import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'
|
|
12
10
|
import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
|
|
13
11
|
|
|
12
|
+
function ensureScope(ctx: CommandRuntimeContext, scope: { tenantId: string; organizationId: string }): void {
|
|
13
|
+
const tenantId = ctx.auth?.tenantId ?? null
|
|
14
|
+
if (tenantId && tenantId !== scope.tenantId) {
|
|
15
|
+
throw new CrudHttpError(403, { error: 'Forbidden' })
|
|
16
|
+
}
|
|
17
|
+
const organizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null
|
|
18
|
+
if (organizationId && organizationId !== scope.organizationId) {
|
|
19
|
+
throw new CrudHttpError(403, { error: 'Forbidden' })
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
14
23
|
async function ensureDictionary(em: EntityManager, id: string): Promise<Dictionary> {
|
|
15
24
|
const dictionary = await em.findOne(Dictionary, {
|
|
16
25
|
id,
|
|
@@ -28,12 +37,12 @@ registerDictionaryEntryCommands({
|
|
|
28
37
|
translationKeyPrefix: 'dictionaries.entries',
|
|
29
38
|
createSchema: dictionaryEntryCommandCreateSchema,
|
|
30
39
|
updateSchema: dictionaryEntryCommandUpdateSchema,
|
|
31
|
-
ensureScope
|
|
40
|
+
ensureScope,
|
|
32
41
|
duplicateError: 'An entry with this value already exists.',
|
|
33
42
|
resolveDictionaryForCreate: async ({ em, ctx, parsed }) => {
|
|
34
43
|
const dictionary = await ensureDictionary(em, parsed.dictionaryId)
|
|
35
44
|
const scope = { tenantId: dictionary.tenantId, organizationId: dictionary.organizationId }
|
|
36
|
-
|
|
45
|
+
ensureScope(ctx, scope)
|
|
37
46
|
return { dictionary, scope }
|
|
38
47
|
},
|
|
39
48
|
resolveEntry: async ({ em, ctx, id }) => {
|
|
@@ -45,7 +54,7 @@ registerDictionaryEntryCommands({
|
|
|
45
54
|
throw new CrudHttpError(404, { error: 'Dictionary not found' })
|
|
46
55
|
}
|
|
47
56
|
const scope = { tenantId: entry.tenantId, organizationId: entry.organizationId }
|
|
48
|
-
|
|
57
|
+
ensureScope(ctx, scope)
|
|
49
58
|
return { entry, dictionary: entry.dictionary, scope }
|
|
50
59
|
},
|
|
51
60
|
ensureDictionaryForUndo: async ({ em, snapshot }) => {
|