@open-mercato/core 0.6.4-develop.4217.1.c9aa050183 → 0.6.4-develop.4239.1.4a264a5828
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/staff_time_entry/index.js +37 -0
- package/dist/generated/entities/staff_time_entry/index.js.map +7 -0
- package/dist/generated/entities/staff_time_entry_segment/index.js +23 -0
- package/dist/generated/entities/staff_time_entry_segment/index.js.map +7 -0
- package/dist/generated/entities/staff_time_project/index.js +35 -0
- package/dist/generated/entities/staff_time_project/index.js.map +7 -0
- package/dist/generated/entities/staff_time_project_member/index.js +29 -0
- package/dist/generated/entities/staff_time_project_member/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +5 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +64 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/timesheetFixtures.js +50 -0
- package/dist/helpers/integration/timesheetFixtures.js.map +7 -0
- package/dist/modules/attachments/api/library/[id]/route.js +20 -16
- package/dist/modules/attachments/api/library/[id]/route.js.map +2 -2
- package/dist/modules/attachments/api/route.js +18 -14
- package/dist/modules/attachments/api/route.js.map +2 -2
- package/dist/modules/auth/api/roles/acl/route.js +10 -4
- package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
- package/dist/modules/auth/api/sidebar/preferences/route.js +27 -20
- package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
- package/dist/modules/auth/api/users/acl/route.js +16 -11
- package/dist/modules/auth/api/users/acl/route.js.map +2 -2
- package/dist/modules/auth/commands/users.js +87 -71
- package/dist/modules/auth/commands/users.js.map +2 -2
- package/dist/modules/auth/services/sidebarPreferencesService.js +39 -30
- package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
- package/dist/modules/business_rules/backend/logs/[id]/page.js +24 -5
- package/dist/modules/business_rules/backend/logs/[id]/page.js.map +2 -2
- package/dist/modules/catalog/api/offers/route.js +15 -5
- package/dist/modules/catalog/api/offers/route.js.map +2 -2
- package/dist/modules/catalog/commands/categories.js +61 -12
- package/dist/modules/catalog/commands/categories.js.map +2 -2
- package/dist/modules/catalog/commands/products.js +79 -54
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/commands/variants.js +29 -16
- package/dist/modules/catalog/commands/variants.js.map +2 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js +19 -2
- package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
- package/dist/modules/currencies/commands/currencies.js +15 -8
- package/dist/modules/currencies/commands/currencies.js.map +2 -2
- package/dist/modules/customer_accounts/api/admin/users.js +27 -26
- package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
- package/dist/modules/customer_accounts/api/password/reset-confirm.js +5 -5
- package/dist/modules/customer_accounts/api/password/reset-confirm.js.map +2 -2
- package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js +11 -10
- package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +27 -7
- package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +27 -7
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/people/[id]/page.js +29 -8
- package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
- package/dist/modules/customers/commands/addresses.js +35 -21
- package/dist/modules/customers/commands/addresses.js.map +2 -2
- package/dist/modules/customers/commands/companies.js +163 -162
- package/dist/modules/customers/commands/companies.js.map +2 -2
- package/dist/modules/customers/commands/deals.js +3 -4
- package/dist/modules/customers/commands/deals.js.map +2 -2
- package/dist/modules/customers/commands/interactions.js +19 -22
- package/dist/modules/customers/commands/interactions.js.map +2 -2
- package/dist/modules/customers/commands/people.js +18 -15
- package/dist/modules/customers/commands/people.js.map +2 -2
- package/dist/modules/customers/commands/personCompanyLinks.js +105 -94
- package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
- package/dist/modules/customers/commands/pipeline-stages.js +30 -23
- package/dist/modules/customers/commands/pipeline-stages.js.map +2 -2
- package/dist/modules/customers/commands/pipelines.js +27 -20
- package/dist/modules/customers/commands/pipelines.js.map +2 -2
- package/dist/modules/customers/commands/tags.js +13 -5
- package/dist/modules/customers/commands/tags.js.map +2 -2
- package/dist/modules/dashboards/api/users/widgets/route.js +0 -1
- package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
- package/dist/modules/dashboards/api/widgets/data/route.js +29 -1
- package/dist/modules/dashboards/api/widgets/data/route.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-engine.js +4 -4
- package/dist/modules/data_sync/lib/sync-engine.js.map +2 -2
- package/dist/modules/data_sync/lib/sync-run-service.js +51 -27
- package/dist/modules/data_sync/lib/sync-run-service.js.map +2 -2
- package/dist/modules/directory/commands/organizations.js +192 -158
- package/dist/modules/directory/commands/organizations.js.map +3 -3
- package/dist/modules/inbox_ops/api/emails/[id]/reprocess/route.js +22 -16
- package/dist/modules/inbox_ops/api/emails/[id]/reprocess/route.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +77 -75
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/messages/commands/shared.js +132 -132
- package/dist/modules/messages/commands/shared.js.map +2 -2
- package/dist/modules/perspectives/api/[tableId]/route.js +37 -26
- package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
- package/dist/modules/progress/acl.js +8 -4
- package/dist/modules/progress/acl.js.map +2 -2
- package/dist/modules/resources/commands/resources.js +125 -117
- package/dist/modules/resources/commands/resources.js.map +2 -2
- package/dist/modules/resources/commands/tags.js +7 -3
- package/dist/modules/resources/commands/tags.js.map +2 -2
- package/dist/modules/sales/api/quotes/send/route.js +12 -11
- package/dist/modules/sales/api/quotes/send/route.js.map +2 -2
- package/dist/modules/sales/commands/documents.js +629 -478
- package/dist/modules/sales/commands/documents.js.map +2 -2
- package/dist/modules/sales/commands/payments.js +146 -146
- package/dist/modules/sales/commands/payments.js.map +2 -2
- package/dist/modules/sales/commands/returns.js +68 -60
- package/dist/modules/sales/commands/returns.js.map +2 -2
- package/dist/modules/staff/acl.js +10 -1
- package/dist/modules/staff/acl.js.map +2 -2
- package/dist/modules/staff/analytics.js +33 -0
- package/dist/modules/staff/analytics.js.map +7 -0
- package/dist/modules/staff/api/guards.js +31 -0
- package/dist/modules/staff/api/guards.js.map +7 -0
- package/dist/modules/staff/api/interceptors.js +96 -0
- package/dist/modules/staff/api/interceptors.js.map +7 -0
- package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js +170 -0
- package/dist/modules/staff/api/timesheets/my-projects/[projectId]/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/my-projects/route.js +103 -0
- package/dist/modules/staff/api/timesheets/my-projects/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/projects/kpis/route.js +147 -0
- package/dist/modules/staff/api/timesheets/projects/kpis/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js +171 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js +180 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/segments/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js +155 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js +173 -0
- package/dist/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js +260 -0
- package/dist/modules/staff/api/timesheets/time-entries/bulk/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-entries/route.js +188 -0
- package/dist/modules/staff/api/timesheets/time-entries/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +159 -0
- package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/time-projects/route.js +230 -0
- package/dist/modules/staff/api/timesheets/time-projects/route.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/page.js +710 -0
- package/dist/modules/staff/backend/staff/timesheets/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/page.meta.js +22 -0
- package/dist/modules/staff/backend/staff/timesheets/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js +125 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js +418 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js +79 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js +16 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/create/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js +602 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js +25 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/page.meta.js.map +7 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js +123 -0
- package/dist/modules/staff/backend/staff/timesheets/projects/projectFormConfig.js.map +7 -0
- package/dist/modules/staff/cli.js +38 -1
- package/dist/modules/staff/cli.js.map +2 -2
- package/dist/modules/staff/commands/index.js +2 -0
- package/dist/modules/staff/commands/index.js.map +2 -2
- package/dist/modules/staff/commands/leave-requests.js +30 -28
- package/dist/modules/staff/commands/leave-requests.js.map +3 -3
- package/dist/modules/staff/commands/team-members.js +21 -20
- package/dist/modules/staff/commands/team-members.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-entries.js +409 -0
- package/dist/modules/staff/commands/timesheets-entries.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-projects.js +618 -0
- package/dist/modules/staff/commands/timesheets-projects.js.map +7 -0
- package/dist/modules/staff/data/enrichers.js +104 -0
- package/dist/modules/staff/data/enrichers.js.map +7 -0
- package/dist/modules/staff/data/entities.js +226 -1
- package/dist/modules/staff/data/entities.js.map +2 -2
- package/dist/modules/staff/data/validators.js +113 -1
- package/dist/modules/staff/data/validators.js.map +2 -2
- package/dist/modules/staff/events.js +13 -1
- package/dist/modules/staff/events.js.map +2 -2
- package/dist/modules/staff/lib/crud.js +7 -1
- package/dist/modules/staff/lib/crud.js.map +2 -2
- package/dist/modules/staff/lib/staffMemberResolver.js +15 -0
- package/dist/modules/staff/lib/staffMemberResolver.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/computeProjectHoursTrend.js +60 -0
- package/dist/modules/staff/lib/timesheets-projects/computeProjectHoursTrend.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/computeProjectsKpis.js +260 -0
- package/dist/modules/staff/lib/timesheets-projects/computeProjectsKpis.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/dateBuckets.js +41 -0
- package/dist/modules/staff/lib/timesheets-projects/dateBuckets.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/initials.js +10 -0
- package/dist/modules/staff/lib/timesheets-projects/initials.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/kpiMath.js +12 -0
- package/dist/modules/staff/lib/timesheets-projects/kpiMath.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects/listProjectMembersPreview.js +55 -0
- package/dist/modules/staff/lib/timesheets-projects/listProjectMembersPreview.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/HoursSparkline.js +66 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/HoursSparkline.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js +81 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectCard.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectMembersAvatarStack.js +58 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectMembersAvatarStack.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsKpiStrip.js +152 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ProjectsKpiStrip.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.js +37 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ViewModeToggle.js +57 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/ViewModeToggle.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/useProjectsViewMode.js +50 -0
- package/dist/modules/staff/lib/timesheets-projects-ui/useProjectsViewMode.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/AddRowDropdown.js +163 -0
- package/dist/modules/staff/lib/timesheets-ui/AddRowDropdown.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/CalendarPicker.js +209 -0
- package/dist/modules/staff/lib/timesheets-ui/CalendarPicker.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/ColorPicker.js +52 -0
- package/dist/modules/staff/lib/timesheets-ui/ColorPicker.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js +77 -0
- package/dist/modules/staff/lib/timesheets-ui/CreateProjectDialog.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/ListView.js +173 -0
- package/dist/modules/staff/lib/timesheets-ui/ListView.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/ProjectColorDot.js +32 -0
- package/dist/modules/staff/lib/timesheets-ui/ProjectColorDot.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/TimerBar.js +270 -0
- package/dist/modules/staff/lib/timesheets-ui/TimerBar.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/ViewSwitcher.js +57 -0
- package/dist/modules/staff/lib/timesheets-ui/ViewSwitcher.js.map +7 -0
- package/dist/modules/staff/lib/timesheets-ui/colors.js +43 -0
- package/dist/modules/staff/lib/timesheets-ui/colors.js.map +7 -0
- package/dist/modules/staff/migrations/Migration20260326135612.js +24 -0
- package/dist/modules/staff/migrations/Migration20260326135612.js.map +7 -0
- package/dist/modules/staff/migrations/Migration20260413102715.js +23 -0
- package/dist/modules/staff/migrations/Migration20260413102715.js.map +7 -0
- package/dist/modules/staff/migrations/Migration20260413111602.js +13 -0
- package/dist/modules/staff/migrations/Migration20260413111602.js.map +7 -0
- package/dist/modules/staff/migrations/Migration20260511112759.js +19 -0
- package/dist/modules/staff/migrations/Migration20260511112759.js.map +7 -0
- package/dist/modules/staff/search.js +35 -0
- package/dist/modules/staff/search.js.map +2 -2
- package/dist/modules/staff/setup.js +15 -1
- package/dist/modules/staff/setup.js.map +2 -2
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/config.js +16 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/config.js.map +7 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.js +126 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.js.map +7 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.js +26 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.js.map +7 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/config.js +15 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/config.js.map +7 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.js +238 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.js.map +7 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.js +26 -0
- package/dist/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.js.map +7 -0
- package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js +145 -0
- package/dist/modules/staff/widgets/injection/timer-sidebar-indicator/widget.js.map +7 -0
- package/dist/modules/staff/widgets/injection-table.js +12 -0
- package/dist/modules/staff/widgets/injection-table.js.map +7 -0
- package/dist/modules/sync_excel/api/import/route.js +19 -17
- package/dist/modules/sync_excel/api/import/route.js.map +2 -2
- package/dist/modules/translations/commands/translations.js +22 -19
- package/dist/modules/translations/commands/translations.js.map +2 -2
- package/dist/modules/workflows/backend/events/[id]/page.js +24 -6
- package/dist/modules/workflows/backend/events/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/instances/[id]/page.js +27 -5
- package/dist/modules/workflows/backend/instances/[id]/page.js.map +2 -2
- package/dist/modules/workflows/backend/tasks/[id]/page.js +25 -6
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/generated/entities/staff_time_entry/index.ts +17 -0
- package/generated/entities/staff_time_entry_segment/index.ts +10 -0
- package/generated/entities/staff_time_project/index.ts +16 -0
- package/generated/entities/staff_time_project_member/index.ts +13 -0
- package/generated/entities.ids.generated.ts +5 -1
- package/generated/entity-fields-registry.ts +64 -0
- package/package.json +7 -7
- package/src/helpers/integration/timesheetFixtures.ts +61 -0
- package/src/modules/attachments/api/library/[id]/route.ts +24 -17
- package/src/modules/attachments/api/route.ts +20 -14
- package/src/modules/auth/api/roles/acl/route.ts +11 -5
- package/src/modules/auth/api/sidebar/preferences/route.ts +33 -24
- package/src/modules/auth/api/users/acl/route.ts +17 -12
- package/src/modules/auth/commands/users.ts +96 -80
- package/src/modules/auth/services/sidebarPreferencesService.ts +40 -32
- package/src/modules/business_rules/backend/logs/[id]/page.tsx +32 -7
- package/src/modules/catalog/api/offers/route.ts +20 -5
- package/src/modules/catalog/commands/categories.ts +61 -12
- package/src/modules/catalog/commands/products.ts +93 -60
- package/src/modules/catalog/commands/variants.ts +29 -16
- package/src/modules/currencies/backend/currencies/[id]/page.tsx +21 -2
- package/src/modules/currencies/commands/currencies.ts +27 -14
- package/src/modules/currencies/i18n/de.json +1 -0
- package/src/modules/currencies/i18n/en.json +1 -0
- package/src/modules/currencies/i18n/es.json +1 -0
- package/src/modules/currencies/i18n/pl.json +1 -0
- package/src/modules/customer_accounts/api/admin/users.ts +31 -26
- package/src/modules/customer_accounts/api/password/reset-confirm.ts +5 -6
- package/src/modules/customer_accounts/api/portal/users/[id]/roles.ts +14 -13
- package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -11
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +34 -11
- package/src/modules/customers/backend/customers/people/[id]/page.tsx +35 -11
- package/src/modules/customers/commands/addresses.ts +35 -23
- package/src/modules/customers/commands/companies.ts +166 -165
- package/src/modules/customers/commands/deals.ts +2 -4
- package/src/modules/customers/commands/interactions.ts +20 -26
- package/src/modules/customers/commands/people.ts +18 -15
- package/src/modules/customers/commands/personCompanyLinks.ts +109 -100
- package/src/modules/customers/commands/pipeline-stages.ts +31 -27
- package/src/modules/customers/commands/pipelines.ts +29 -23
- package/src/modules/customers/commands/tags.ts +13 -5
- package/src/modules/dashboards/api/users/widgets/route.ts +0 -1
- package/src/modules/dashboards/api/widgets/data/route.ts +36 -1
- package/src/modules/data_sync/lib/sync-engine.ts +4 -5
- package/src/modules/data_sync/lib/sync-run-service.ts +57 -28
- package/src/modules/directory/commands/organizations.ts +203 -166
- package/src/modules/inbox_ops/api/emails/[id]/reprocess/route.ts +26 -18
- package/src/modules/messages/commands/messages.ts +82 -80
- package/src/modules/messages/commands/shared.ts +138 -133
- package/src/modules/perspectives/api/[tableId]/route.ts +38 -27
- package/src/modules/progress/acl.ts +4 -0
- package/src/modules/resources/commands/resources.ts +127 -117
- package/src/modules/resources/commands/tags.ts +7 -3
- package/src/modules/sales/api/quotes/send/route.ts +17 -12
- package/src/modules/sales/commands/documents.ts +673 -481
- package/src/modules/sales/commands/payments.ts +158 -152
- package/src/modules/sales/commands/returns.ts +74 -63
- package/src/modules/staff/acl.ts +11 -0
- package/src/modules/staff/analytics.ts +30 -0
- package/src/modules/staff/api/guards.ts +59 -0
- package/src/modules/staff/api/interceptors.ts +122 -0
- package/src/modules/staff/api/timesheets/my-projects/[projectId]/route.ts +191 -0
- package/src/modules/staff/api/timesheets/my-projects/route.ts +115 -0
- package/src/modules/staff/api/timesheets/projects/kpis/route.ts +159 -0
- package/src/modules/staff/api/timesheets/time-entries/[id]/segments/[segmentId]/route.ts +187 -0
- package/src/modules/staff/api/timesheets/time-entries/[id]/segments/route.ts +191 -0
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-start/route.ts +168 -0
- package/src/modules/staff/api/timesheets/time-entries/[id]/timer-stop/route.ts +191 -0
- package/src/modules/staff/api/timesheets/time-entries/bulk/route.ts +292 -0
- package/src/modules/staff/api/timesheets/time-entries/route.ts +193 -0
- package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +167 -0
- package/src/modules/staff/api/timesheets/time-projects/route.ts +244 -0
- package/src/modules/staff/backend/staff/timesheets/page.meta.ts +20 -0
- package/src/modules/staff/backend/staff/timesheets/page.tsx +899 -0
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/edit/page.tsx +141 -0
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +579 -0
- package/src/modules/staff/backend/staff/timesheets/projects/create/page.meta.ts +12 -0
- package/src/modules/staff/backend/staff/timesheets/projects/create/page.tsx +90 -0
- package/src/modules/staff/backend/staff/timesheets/projects/page.meta.ts +23 -0
- package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +765 -0
- package/src/modules/staff/backend/staff/timesheets/projects/projectFormConfig.ts +138 -0
- package/src/modules/staff/cli.ts +40 -1
- package/src/modules/staff/commands/index.ts +2 -0
- package/src/modules/staff/commands/leave-requests.ts +37 -29
- package/src/modules/staff/commands/team-members.ts +25 -20
- package/src/modules/staff/commands/timesheets-entries.ts +504 -0
- package/src/modules/staff/commands/timesheets-projects.ts +699 -0
- package/src/modules/staff/data/enrichers.ts +134 -0
- package/src/modules/staff/data/entities.ts +198 -0
- package/src/modules/staff/data/validators.ts +129 -0
- package/src/modules/staff/events.ts +13 -0
- package/src/modules/staff/i18n/de.json +209 -1
- package/src/modules/staff/i18n/en.json +209 -1
- package/src/modules/staff/i18n/es.json +209 -1
- package/src/modules/staff/i18n/pl.json +209 -1
- package/src/modules/staff/lib/crud.ts +8 -0
- package/src/modules/staff/lib/staffMemberResolver.ts +22 -0
- package/src/modules/staff/lib/timesheets-projects/computeProjectHoursTrend.ts +89 -0
- package/src/modules/staff/lib/timesheets-projects/computeProjectsKpis.ts +311 -0
- package/src/modules/staff/lib/timesheets-projects/dateBuckets.ts +37 -0
- package/src/modules/staff/lib/timesheets-projects/initials.ts +6 -0
- package/src/modules/staff/lib/timesheets-projects/kpiMath.ts +8 -0
- package/src/modules/staff/lib/timesheets-projects/listProjectMembersPreview.ts +83 -0
- package/src/modules/staff/lib/timesheets-projects-ui/HoursSparkline.tsx +75 -0
- package/src/modules/staff/lib/timesheets-projects-ui/ProjectCard.tsx +110 -0
- package/src/modules/staff/lib/timesheets-projects-ui/ProjectMembersAvatarStack.tsx +73 -0
- package/src/modules/staff/lib/timesheets-projects-ui/ProjectsKpiStrip.tsx +185 -0
- package/src/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.tsx +53 -0
- package/src/modules/staff/lib/timesheets-projects-ui/ViewModeToggle.tsx +63 -0
- package/src/modules/staff/lib/timesheets-projects-ui/useProjectsViewMode.ts +63 -0
- package/src/modules/staff/lib/timesheets-ui/AddRowDropdown.tsx +188 -0
- package/src/modules/staff/lib/timesheets-ui/CalendarPicker.tsx +229 -0
- package/src/modules/staff/lib/timesheets-ui/ColorPicker.tsx +65 -0
- package/src/modules/staff/lib/timesheets-ui/CreateProjectDialog.tsx +99 -0
- package/src/modules/staff/lib/timesheets-ui/ListView.tsx +230 -0
- package/src/modules/staff/lib/timesheets-ui/ProjectColorDot.tsx +40 -0
- package/src/modules/staff/lib/timesheets-ui/TimerBar.tsx +327 -0
- package/src/modules/staff/lib/timesheets-ui/ViewSwitcher.tsx +60 -0
- package/src/modules/staff/lib/timesheets-ui/colors.ts +58 -0
- package/src/modules/staff/migrations/.snapshot-open-mercato.json +1148 -0
- package/src/modules/staff/migrations/Migration20260326135612.ts +26 -0
- package/src/modules/staff/migrations/Migration20260413102715.ts +25 -0
- package/src/modules/staff/migrations/Migration20260413111602.ts +13 -0
- package/src/modules/staff/migrations/Migration20260511112759.ts +21 -0
- package/src/modules/staff/search.ts +35 -0
- package/src/modules/staff/setup.ts +15 -0
- package/src/modules/staff/widgets/dashboard/timesheets-hours-by-project/config.ts +17 -0
- package/src/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.client.tsx +158 -0
- package/src/modules/staff/widgets/dashboard/timesheets-hours-by-project/widget.ts +25 -0
- package/src/modules/staff/widgets/dashboard/timesheets-time-reporting/config.ts +15 -0
- package/src/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.client.tsx +297 -0
- package/src/modules/staff/widgets/dashboard/timesheets-time-reporting/widget.ts +25 -0
- package/src/modules/staff/widgets/injection/timer-sidebar-indicator/widget.tsx +161 -0
- package/src/modules/staff/widgets/injection-table.ts +10 -0
- package/src/modules/sync_excel/api/import/route.ts +23 -18
- package/src/modules/translations/commands/translations.ts +49 -41
- package/src/modules/workflows/backend/events/[id]/page.tsx +32 -10
- package/src/modules/workflows/backend/instances/[id]/page.tsx +33 -9
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +33 -10
- package/src/modules/workflows/i18n/de.json +1 -0
- package/src/modules/workflows/i18n/en.json +1 -0
- package/src/modules/workflows/i18n/es.json +1 -0
- package/src/modules/workflows/i18n/pl.json +1 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
const AVATAR_PALETTE = [
|
|
4
|
+
"bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-200",
|
|
5
|
+
"bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200",
|
|
6
|
+
"bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-200",
|
|
7
|
+
"bg-rose-100 text-rose-800 dark:bg-rose-900/40 dark:text-rose-200",
|
|
8
|
+
"bg-violet-100 text-violet-800 dark:bg-violet-900/40 dark:text-violet-200",
|
|
9
|
+
"bg-cyan-100 text-cyan-800 dark:bg-cyan-900/40 dark:text-cyan-200"
|
|
10
|
+
];
|
|
11
|
+
function pickPalette(id) {
|
|
12
|
+
let hash = 0;
|
|
13
|
+
for (let i = 0; i < id.length; i++) {
|
|
14
|
+
hash = hash * 31 + id.charCodeAt(i) | 0;
|
|
15
|
+
}
|
|
16
|
+
return AVATAR_PALETTE[Math.abs(hash) % AVATAR_PALETTE.length];
|
|
17
|
+
}
|
|
18
|
+
function ProjectMembersAvatarStack({
|
|
19
|
+
members,
|
|
20
|
+
total,
|
|
21
|
+
peopleCountLabel,
|
|
22
|
+
className
|
|
23
|
+
}) {
|
|
24
|
+
const visible = members.slice(0, 4);
|
|
25
|
+
const overflow = Math.max(0, total - visible.length);
|
|
26
|
+
if (total === 0) {
|
|
27
|
+
return /* @__PURE__ */ jsx("span", { className: `text-xs text-muted-foreground ${className ?? ""}`, children: "\u2014" });
|
|
28
|
+
}
|
|
29
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-2 ${className ?? ""}`, children: [
|
|
30
|
+
/* @__PURE__ */ jsxs("div", { className: "flex -space-x-1.5", children: [
|
|
31
|
+
visible.map((member) => /* @__PURE__ */ jsx(
|
|
32
|
+
"span",
|
|
33
|
+
{
|
|
34
|
+
title: member.name,
|
|
35
|
+
className: `inline-flex h-6 w-6 items-center justify-center rounded-full border border-background text-[10px] font-semibold ${pickPalette(member.id)}`,
|
|
36
|
+
children: member.initials
|
|
37
|
+
},
|
|
38
|
+
member.id
|
|
39
|
+
)),
|
|
40
|
+
overflow > 0 ? /* @__PURE__ */ jsxs(
|
|
41
|
+
"span",
|
|
42
|
+
{
|
|
43
|
+
className: "inline-flex h-6 w-6 items-center justify-center rounded-full border border-background bg-muted text-[10px] font-semibold text-foreground",
|
|
44
|
+
title: `+${overflow}`,
|
|
45
|
+
children: [
|
|
46
|
+
"+",
|
|
47
|
+
overflow
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
) : null
|
|
51
|
+
] }),
|
|
52
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: peopleCountLabel })
|
|
53
|
+
] });
|
|
54
|
+
}
|
|
55
|
+
export {
|
|
56
|
+
ProjectMembersAvatarStack
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=ProjectMembersAvatarStack.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/staff/lib/timesheets-projects-ui/ProjectMembersAvatarStack.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\n\nexport type AvatarMember = {\n id: string\n name: string\n initials: string\n avatarUrl?: string | null\n}\n\nexport type ProjectMembersAvatarStackProps = {\n members: AvatarMember[]\n total: number\n peopleCountLabel: string\n className?: string\n}\n\nconst AVATAR_PALETTE = [\n 'bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-200',\n 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/40 dark:text-emerald-200',\n 'bg-amber-100 text-amber-800 dark:bg-amber-900/40 dark:text-amber-200',\n 'bg-rose-100 text-rose-800 dark:bg-rose-900/40 dark:text-rose-200',\n 'bg-violet-100 text-violet-800 dark:bg-violet-900/40 dark:text-violet-200',\n 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900/40 dark:text-cyan-200',\n]\n\nfunction pickPalette(id: string): string {\n let hash = 0\n for (let i = 0; i < id.length; i++) {\n hash = (hash * 31 + id.charCodeAt(i)) | 0\n }\n return AVATAR_PALETTE[Math.abs(hash) % AVATAR_PALETTE.length]\n}\n\nexport function ProjectMembersAvatarStack({\n members,\n total,\n peopleCountLabel,\n className,\n}: ProjectMembersAvatarStackProps) {\n const visible = members.slice(0, 4)\n const overflow = Math.max(0, total - visible.length)\n\n if (total === 0) {\n return <span className={`text-xs text-muted-foreground ${className ?? ''}`}>\u2014</span>\n }\n\n return (\n <div className={`flex items-center gap-2 ${className ?? ''}`}>\n <div className=\"flex -space-x-1.5\">\n {visible.map((member) => (\n <span\n key={member.id}\n title={member.name}\n className={`inline-flex h-6 w-6 items-center justify-center rounded-full border border-background text-[10px] font-semibold ${pickPalette(member.id)}`}\n >\n {member.initials}\n </span>\n ))}\n {overflow > 0 ? (\n <span\n className=\"inline-flex h-6 w-6 items-center justify-center rounded-full border border-background bg-muted text-[10px] font-semibold text-foreground\"\n title={`+${overflow}`}\n >\n +{overflow}\n </span>\n ) : null}\n </div>\n <span className=\"text-xs text-muted-foreground\">{peopleCountLabel}</span>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AA6CW,cAgBD,YAhBC;AA3BX,MAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,YAAY,IAAoB;AACvC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,IAAI,GAAG,QAAQ,KAAK;AAClC,WAAQ,OAAO,KAAK,GAAG,WAAW,CAAC,IAAK;AAAA,EAC1C;AACA,SAAO,eAAe,KAAK,IAAI,IAAI,IAAI,eAAe,MAAM;AAC9D;AAEO,SAAS,0BAA0B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmC;AACjC,QAAM,UAAU,QAAQ,MAAM,GAAG,CAAC;AAClC,QAAM,WAAW,KAAK,IAAI,GAAG,QAAQ,QAAQ,MAAM;AAEnD,MAAI,UAAU,GAAG;AACf,WAAO,oBAAC,UAAK,WAAW,iCAAiC,aAAa,EAAE,IAAI,oBAAC;AAAA,EAC/E;AAEA,SACE,qBAAC,SAAI,WAAW,2BAA2B,aAAa,EAAE,IACxD;AAAA,yBAAC,SAAI,WAAU,qBACZ;AAAA,cAAQ,IAAI,CAAC,WACZ;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,OAAO;AAAA,UACd,WAAW,mHAAmH,YAAY,OAAO,EAAE,CAAC;AAAA,UAEnJ,iBAAO;AAAA;AAAA,QAJH,OAAO;AAAA,MAKd,CACD;AAAA,MACA,WAAW,IACV;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,OAAO,IAAI,QAAQ;AAAA,UACpB;AAAA;AAAA,YACG;AAAA;AAAA;AAAA,MACJ,IACE;AAAA,OACN;AAAA,IACA,oBAAC,UAAK,WAAU,iCAAiC,4BAAiB;AAAA,KACpE;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ArrowDownRight, ArrowUpRight, Minus } from "lucide-react";
|
|
4
|
+
function DeltaBadge({ pct, labels }) {
|
|
5
|
+
if (pct === null) {
|
|
6
|
+
return /* @__PURE__ */ jsx("span", { className: "text-[11px] text-muted-foreground/70", children: labels.noPrevious });
|
|
7
|
+
}
|
|
8
|
+
if (pct > 0) {
|
|
9
|
+
return /* @__PURE__ */ jsxs(
|
|
10
|
+
"span",
|
|
11
|
+
{
|
|
12
|
+
className: "inline-flex items-center gap-0.5 text-[11px] font-medium text-emerald-600 tabular-nums",
|
|
13
|
+
"aria-label": labels.deltaUp(pct),
|
|
14
|
+
children: [
|
|
15
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
16
|
+
pct,
|
|
17
|
+
"%"
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (pct < 0) {
|
|
23
|
+
return /* @__PURE__ */ jsxs(
|
|
24
|
+
"span",
|
|
25
|
+
{
|
|
26
|
+
className: "inline-flex items-center gap-0.5 text-[11px] font-medium text-rose-600 tabular-nums",
|
|
27
|
+
"aria-label": labels.deltaDown(Math.abs(pct)),
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ jsx(ArrowDownRight, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
30
|
+
Math.abs(pct),
|
|
31
|
+
"%"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
return /* @__PURE__ */ jsxs(
|
|
37
|
+
"span",
|
|
38
|
+
{
|
|
39
|
+
className: "inline-flex items-center gap-0.5 text-[11px] text-muted-foreground/70",
|
|
40
|
+
"aria-label": labels.deltaFlat,
|
|
41
|
+
children: [
|
|
42
|
+
/* @__PURE__ */ jsx(Minus, { className: "h-3 w-3", "aria-hidden": "true" }),
|
|
43
|
+
"0%"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
function KpiCard({
|
|
49
|
+
label,
|
|
50
|
+
value,
|
|
51
|
+
subtext,
|
|
52
|
+
delta,
|
|
53
|
+
labels
|
|
54
|
+
}) {
|
|
55
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 rounded-lg border border-border bg-card p-4", children: [
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
57
|
+
/* @__PURE__ */ jsx("p", { className: "text-[11px] uppercase tracking-wide text-muted-foreground", children: label }),
|
|
58
|
+
delta ? /* @__PURE__ */ jsx(DeltaBadge, { pct: delta.deltaPct, labels }) : null
|
|
59
|
+
] }),
|
|
60
|
+
/* @__PURE__ */ jsx("p", { className: "text-2xl font-semibold tabular-nums text-foreground", children: value }),
|
|
61
|
+
subtext ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: subtext }) : null
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
function ProjectsKpiStrip({ kpis, labels, isLoading }) {
|
|
65
|
+
if (isLoading || !kpis) {
|
|
66
|
+
return /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-5", children: Array.from({ length: 5 }).map((_, idx) => /* @__PURE__ */ jsx("div", { className: "h-[88px] animate-pulse rounded-lg border border-border bg-muted/40" }, idx)) });
|
|
67
|
+
}
|
|
68
|
+
if (kpis.role === "pm") {
|
|
69
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-5", children: [
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
KpiCard,
|
|
72
|
+
{
|
|
73
|
+
label: labels.totalProjects,
|
|
74
|
+
value: kpis.totals.total,
|
|
75
|
+
subtext: labels.totalProjectsSub({ active: kpis.totals.active, onHold: kpis.totals.onHold }),
|
|
76
|
+
labels
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
/* @__PURE__ */ jsx(
|
|
80
|
+
KpiCard,
|
|
81
|
+
{
|
|
82
|
+
label: labels.hoursWeek,
|
|
83
|
+
value: `${kpis.hoursWeek.current}h`,
|
|
84
|
+
subtext: labels.hoursWeekSub,
|
|
85
|
+
delta: kpis.hoursWeek,
|
|
86
|
+
labels
|
|
87
|
+
}
|
|
88
|
+
),
|
|
89
|
+
/* @__PURE__ */ jsx(
|
|
90
|
+
KpiCard,
|
|
91
|
+
{
|
|
92
|
+
label: labels.hoursMonth,
|
|
93
|
+
value: `${kpis.hoursMonth.current}h`,
|
|
94
|
+
subtext: labels.hoursMonthSub,
|
|
95
|
+
delta: kpis.hoursMonth,
|
|
96
|
+
labels
|
|
97
|
+
}
|
|
98
|
+
),
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
KpiCard,
|
|
101
|
+
{
|
|
102
|
+
label: labels.assignedToMe,
|
|
103
|
+
value: kpis.assignedToMe.total,
|
|
104
|
+
subtext: labels.assignedToMeSub(kpis.assignedToMe.active),
|
|
105
|
+
labels
|
|
106
|
+
}
|
|
107
|
+
),
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
KpiCard,
|
|
110
|
+
{
|
|
111
|
+
label: labels.teamActive,
|
|
112
|
+
value: kpis.teamActive.count,
|
|
113
|
+
subtext: labels.teamActiveSub,
|
|
114
|
+
labels
|
|
115
|
+
}
|
|
116
|
+
)
|
|
117
|
+
] });
|
|
118
|
+
}
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-3", children: [
|
|
120
|
+
/* @__PURE__ */ jsx(
|
|
121
|
+
KpiCard,
|
|
122
|
+
{
|
|
123
|
+
label: labels.myProjects,
|
|
124
|
+
value: kpis.myProjects.total,
|
|
125
|
+
subtext: labels.myProjectsSub(kpis.myProjects.active),
|
|
126
|
+
labels
|
|
127
|
+
}
|
|
128
|
+
),
|
|
129
|
+
/* @__PURE__ */ jsx(
|
|
130
|
+
KpiCard,
|
|
131
|
+
{
|
|
132
|
+
label: labels.myHoursWeek,
|
|
133
|
+
value: `${kpis.myHoursWeek.current}h`,
|
|
134
|
+
delta: kpis.myHoursWeek,
|
|
135
|
+
labels
|
|
136
|
+
}
|
|
137
|
+
),
|
|
138
|
+
/* @__PURE__ */ jsx(
|
|
139
|
+
KpiCard,
|
|
140
|
+
{
|
|
141
|
+
label: labels.myHoursMonth,
|
|
142
|
+
value: `${kpis.myHoursMonth.current}h`,
|
|
143
|
+
delta: kpis.myHoursMonth,
|
|
144
|
+
labels
|
|
145
|
+
}
|
|
146
|
+
)
|
|
147
|
+
] });
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
ProjectsKpiStrip
|
|
151
|
+
};
|
|
152
|
+
//# sourceMappingURL=ProjectsKpiStrip.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/staff/lib/timesheets-projects-ui/ProjectsKpiStrip.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { ArrowDownRight, ArrowUpRight, Minus } from 'lucide-react'\n\ntype Delta = { current: number; previous: number; deltaPct: number | null }\n\nexport type PmKpis = {\n role: 'pm'\n totals: { total: number; active: number; onHold: number; completed: number }\n hoursWeek: Delta\n hoursMonth: Delta\n teamActive: { count: number }\n assignedToMe: { total: number; active: number }\n}\n\nexport type CollabKpis = {\n role: 'collab'\n myProjects: { total: number; active: number }\n myHoursWeek: Delta\n myHoursMonth: Delta\n}\n\ntype KpiLabels = {\n totalProjects: string\n totalProjectsSub: (args: { active: number; onHold: number }) => string\n hoursWeek: string\n hoursWeekSub: string\n assignedToMe: string\n assignedToMeSub: (active: number) => string\n hoursMonth: string\n hoursMonthSub: string\n teamActive: string\n teamActiveSub: string\n myProjects: string\n myProjectsSub: (active: number) => string\n myHoursWeek: string\n myHoursMonth: string\n deltaUp: (pct: number) => string\n deltaDown: (pct: number) => string\n deltaFlat: string\n noPrevious: string\n}\n\nfunction DeltaBadge({ pct, labels }: { pct: number | null; labels: KpiLabels }) {\n if (pct === null) {\n return <span className=\"text-[11px] text-muted-foreground/70\">{labels.noPrevious}</span>\n }\n if (pct > 0) {\n return (\n <span\n className=\"inline-flex items-center gap-0.5 text-[11px] font-medium text-emerald-600 tabular-nums\"\n aria-label={labels.deltaUp(pct)}\n >\n <ArrowUpRight className=\"h-3 w-3\" aria-hidden=\"true\" />\n {pct}%\n </span>\n )\n }\n if (pct < 0) {\n return (\n <span\n className=\"inline-flex items-center gap-0.5 text-[11px] font-medium text-rose-600 tabular-nums\"\n aria-label={labels.deltaDown(Math.abs(pct))}\n >\n <ArrowDownRight className=\"h-3 w-3\" aria-hidden=\"true\" />\n {Math.abs(pct)}%\n </span>\n )\n }\n return (\n <span\n className=\"inline-flex items-center gap-0.5 text-[11px] text-muted-foreground/70\"\n aria-label={labels.deltaFlat}\n >\n <Minus className=\"h-3 w-3\" aria-hidden=\"true\" />\n 0%\n </span>\n )\n}\n\nfunction KpiCard({\n label,\n value,\n subtext,\n delta,\n labels,\n}: {\n label: string\n value: React.ReactNode\n subtext?: string\n delta?: Delta\n labels: KpiLabels\n}) {\n return (\n <div className=\"flex flex-col gap-1 rounded-lg border border-border bg-card p-4\">\n <div className=\"flex items-center justify-between gap-2\">\n <p className=\"text-[11px] uppercase tracking-wide text-muted-foreground\">{label}</p>\n {delta ? <DeltaBadge pct={delta.deltaPct} labels={labels} /> : null}\n </div>\n <p className=\"text-2xl font-semibold tabular-nums text-foreground\">{value}</p>\n {subtext ? <p className=\"text-xs text-muted-foreground\">{subtext}</p> : null}\n </div>\n )\n}\n\nexport type ProjectsKpiStripProps = {\n kpis: PmKpis | CollabKpis | null\n labels: KpiLabels\n isLoading?: boolean\n}\n\nexport function ProjectsKpiStrip({ kpis, labels, isLoading }: ProjectsKpiStripProps) {\n if (isLoading || !kpis) {\n return (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-5\">\n {Array.from({ length: 5 }).map((_, idx) => (\n <div key={idx} className=\"h-[88px] animate-pulse rounded-lg border border-border bg-muted/40\" />\n ))}\n </div>\n )\n }\n\n if (kpis.role === 'pm') {\n return (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-5\">\n <KpiCard\n label={labels.totalProjects}\n value={kpis.totals.total}\n subtext={labels.totalProjectsSub({ active: kpis.totals.active, onHold: kpis.totals.onHold })}\n labels={labels}\n />\n <KpiCard\n label={labels.hoursWeek}\n value={`${kpis.hoursWeek.current}h`}\n subtext={labels.hoursWeekSub}\n delta={kpis.hoursWeek}\n labels={labels}\n />\n <KpiCard\n label={labels.hoursMonth}\n value={`${kpis.hoursMonth.current}h`}\n subtext={labels.hoursMonthSub}\n delta={kpis.hoursMonth}\n labels={labels}\n />\n <KpiCard\n label={labels.assignedToMe}\n value={kpis.assignedToMe.total}\n subtext={labels.assignedToMeSub(kpis.assignedToMe.active)}\n labels={labels}\n />\n <KpiCard\n label={labels.teamActive}\n value={kpis.teamActive.count}\n subtext={labels.teamActiveSub}\n labels={labels}\n />\n </div>\n )\n }\n\n return (\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-3\">\n <KpiCard\n label={labels.myProjects}\n value={kpis.myProjects.total}\n subtext={labels.myProjectsSub(kpis.myProjects.active)}\n labels={labels}\n />\n <KpiCard\n label={labels.myHoursWeek}\n value={`${kpis.myHoursWeek.current}h`}\n delta={kpis.myHoursWeek}\n labels={labels}\n />\n <KpiCard\n label={labels.myHoursMonth}\n value={`${kpis.myHoursMonth.current}h`}\n delta={kpis.myHoursMonth}\n labels={labels}\n />\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
4
|
+
function SavedViewTabs({ tabs, activeId, onSelect, className, ariaLabel }) {
|
|
5
|
+
return /* @__PURE__ */ jsx(
|
|
6
|
+
"div",
|
|
7
|
+
{
|
|
8
|
+
role: "tablist",
|
|
9
|
+
"aria-label": ariaLabel ?? "Saved views",
|
|
10
|
+
className: `flex items-center gap-1 border-b border-border ${className ?? ""}`,
|
|
11
|
+
children: tabs.map((tab) => {
|
|
12
|
+
const isActive = tab.id === activeId;
|
|
13
|
+
return /* @__PURE__ */ jsxs(
|
|
14
|
+
Button,
|
|
15
|
+
{
|
|
16
|
+
type: "button",
|
|
17
|
+
variant: "ghost",
|
|
18
|
+
size: "sm",
|
|
19
|
+
role: "tab",
|
|
20
|
+
"aria-selected": isActive,
|
|
21
|
+
className: `h-auto rounded-none px-3 py-2 text-sm hover:bg-transparent ${isActive ? "border-b-2 border-foreground font-medium text-foreground" : "border-b-2 border-transparent text-muted-foreground hover:text-foreground"}`,
|
|
22
|
+
onClick: () => onSelect(tab.id),
|
|
23
|
+
children: [
|
|
24
|
+
tab.label,
|
|
25
|
+
typeof tab.count === "number" ? /* @__PURE__ */ jsx("span", { className: "ml-1.5 text-xs text-muted-foreground/70 tabular-nums", children: tab.count }) : null
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
tab.id
|
|
29
|
+
);
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
SavedViewTabs
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=SavedViewTabs.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\n\nexport type SavedViewTab = {\n id: string\n label: string\n count?: number\n}\n\nexport type SavedViewTabsProps = {\n tabs: SavedViewTab[]\n activeId: string\n onSelect: (id: string) => void\n className?: string\n ariaLabel?: string\n}\n\nexport function SavedViewTabs({ tabs, activeId, onSelect, className, ariaLabel }: SavedViewTabsProps) {\n return (\n <div\n role=\"tablist\"\n aria-label={ariaLabel ?? 'Saved views'}\n className={`flex items-center gap-1 border-b border-border ${className ?? ''}`}\n >\n {tabs.map((tab) => {\n const isActive = tab.id === activeId\n return (\n <Button\n key={tab.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n role=\"tab\"\n aria-selected={isActive}\n className={`h-auto rounded-none px-3 py-2 text-sm hover:bg-transparent ${\n isActive\n ? 'border-b-2 border-foreground font-medium text-foreground'\n : 'border-b-2 border-transparent text-muted-foreground hover:text-foreground'\n }`}\n onClick={() => onSelect(tab.id)}\n >\n {tab.label}\n {typeof tab.count === 'number' ? (\n <span className=\"ml-1.5 text-xs text-muted-foreground/70 tabular-nums\">{tab.count}</span>\n ) : null}\n </Button>\n )\n })}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AA6BU,SAgBI,KAhBJ;AA1BV,SAAS,cAAc;AAgBhB,SAAS,cAAc,EAAE,MAAM,UAAU,UAAU,WAAW,UAAU,GAAuB;AACpG,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY,aAAa;AAAA,MACzB,WAAW,kDAAkD,aAAa,EAAE;AAAA,MAE3E,eAAK,IAAI,CAAC,QAAQ;AACjB,cAAM,WAAW,IAAI,OAAO;AAC5B,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,MAAK;AAAA,YACL,iBAAe;AAAA,YACf,WAAW,8DACT,WACI,6DACA,2EACN;AAAA,YACA,SAAS,MAAM,SAAS,IAAI,EAAE;AAAA,YAE7B;AAAA,kBAAI;AAAA,cACJ,OAAO,IAAI,UAAU,WACpB,oBAAC,UAAK,WAAU,wDAAwD,cAAI,OAAM,IAChF;AAAA;AAAA;AAAA,UAhBC,IAAI;AAAA,QAiBX;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { LayoutGrid, List } from "lucide-react";
|
|
4
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
5
|
+
function ViewModeToggle({
|
|
6
|
+
mode,
|
|
7
|
+
onChange,
|
|
8
|
+
tableLabel,
|
|
9
|
+
cardsLabel,
|
|
10
|
+
className,
|
|
11
|
+
ariaLabel
|
|
12
|
+
}) {
|
|
13
|
+
return /* @__PURE__ */ jsxs(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
role: "group",
|
|
17
|
+
"aria-label": ariaLabel ?? "View mode",
|
|
18
|
+
className: `inline-flex items-center rounded-md border border-border p-0.5 ${className ?? ""}`,
|
|
19
|
+
children: [
|
|
20
|
+
/* @__PURE__ */ jsxs(
|
|
21
|
+
Button,
|
|
22
|
+
{
|
|
23
|
+
type: "button",
|
|
24
|
+
variant: "ghost",
|
|
25
|
+
size: "sm",
|
|
26
|
+
"aria-pressed": mode === "table",
|
|
27
|
+
className: `h-auto gap-1.5 px-2.5 py-1 text-xs ${mode === "table" ? "bg-foreground text-background hover:bg-foreground" : "text-muted-foreground hover:bg-muted"}`,
|
|
28
|
+
onClick: () => onChange("table"),
|
|
29
|
+
children: [
|
|
30
|
+
/* @__PURE__ */ jsx(List, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
31
|
+
tableLabel
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
/* @__PURE__ */ jsxs(
|
|
36
|
+
Button,
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
variant: "ghost",
|
|
40
|
+
size: "sm",
|
|
41
|
+
"aria-pressed": mode === "cards",
|
|
42
|
+
className: `h-auto gap-1.5 px-2.5 py-1 text-xs ${mode === "cards" ? "bg-foreground text-background hover:bg-foreground" : "text-muted-foreground hover:bg-muted"}`,
|
|
43
|
+
onClick: () => onChange("cards"),
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ jsx(LayoutGrid, { className: "h-3.5 w-3.5", "aria-hidden": "true" }),
|
|
46
|
+
cardsLabel
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
export {
|
|
55
|
+
ViewModeToggle
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=ViewModeToggle.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/staff/lib/timesheets-projects-ui/ViewModeToggle.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { LayoutGrid, List } from 'lucide-react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport type { ProjectsViewMode } from './useProjectsViewMode'\n\nexport type ViewModeToggleProps = {\n mode: ProjectsViewMode\n onChange: (mode: ProjectsViewMode) => void\n tableLabel: string\n cardsLabel: string\n className?: string\n ariaLabel?: string\n}\n\nexport function ViewModeToggle({\n mode,\n onChange,\n tableLabel,\n cardsLabel,\n className,\n ariaLabel,\n}: ViewModeToggleProps) {\n return (\n <div\n role=\"group\"\n aria-label={ariaLabel ?? 'View mode'}\n className={`inline-flex items-center rounded-md border border-border p-0.5 ${className ?? ''}`}\n >\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-pressed={mode === 'table'}\n className={`h-auto gap-1.5 px-2.5 py-1 text-xs ${\n mode === 'table'\n ? 'bg-foreground text-background hover:bg-foreground'\n : 'text-muted-foreground hover:bg-muted'\n }`}\n onClick={() => onChange('table')}\n >\n <List className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {tableLabel}\n </Button>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n aria-pressed={mode === 'cards'}\n className={`h-auto gap-1.5 px-2.5 py-1 text-xs ${\n mode === 'cards'\n ? 'bg-foreground text-background hover:bg-foreground'\n : 'text-muted-foreground hover:bg-muted'\n }`}\n onClick={() => onChange('cards')}\n >\n <LayoutGrid className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n {cardsLabel}\n </Button>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": ";AA8BM,SAYE,KAZF;AA3BN,SAAS,YAAY,YAAY;AACjC,SAAS,cAAc;AAYhB,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,cAAY,aAAa;AAAA,MACzB,WAAW,kEAAkE,aAAa,EAAE;AAAA,MAE5F;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,gBAAc,SAAS;AAAA,YACvB,WAAW,sCACT,SAAS,UACL,sDACA,sCACN;AAAA,YACA,SAAS,MAAM,SAAS,OAAO;AAAA,YAE/B;AAAA,kCAAC,QAAK,WAAU,eAAc,eAAY,QAAO;AAAA,cAChD;AAAA;AAAA;AAAA,QACH;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,gBAAc,SAAS;AAAA,YACvB,WAAW,sCACT,SAAS,UACL,sDACA,sCACN;AAAA,YACA,SAAS,MAAM,SAAS,OAAO;AAAA,YAE/B;AAAA,kCAAC,cAAW,WAAU,eAAc,eAAY,QAAO;AAAA,cACtD;AAAA;AAAA;AAAA,QACH;AAAA;AAAA;AAAA,EACF;AAEJ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
const STORAGE_KEY_PREFIX = "staff.timesheets.projects.viewMode";
|
|
4
|
+
function storageKey(userKey) {
|
|
5
|
+
return userKey ? `${STORAGE_KEY_PREFIX}:${userKey}` : STORAGE_KEY_PREFIX;
|
|
6
|
+
}
|
|
7
|
+
function readStoredMode(userKey) {
|
|
8
|
+
if (typeof window === "undefined") return null;
|
|
9
|
+
try {
|
|
10
|
+
const raw = window.localStorage.getItem(storageKey(userKey));
|
|
11
|
+
return raw === "cards" || raw === "table" ? raw : null;
|
|
12
|
+
} catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function writeStoredMode(userKey, mode) {
|
|
17
|
+
if (typeof window === "undefined") return;
|
|
18
|
+
try {
|
|
19
|
+
window.localStorage.setItem(storageKey(userKey), mode);
|
|
20
|
+
} catch {
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function useProjectsViewMode({
|
|
24
|
+
userKey,
|
|
25
|
+
urlOverride,
|
|
26
|
+
fallback = "table"
|
|
27
|
+
}) {
|
|
28
|
+
const initial = React.useMemo(() => {
|
|
29
|
+
if (urlOverride === "cards" || urlOverride === "table") return urlOverride;
|
|
30
|
+
return readStoredMode(userKey) ?? fallback;
|
|
31
|
+
}, [urlOverride, userKey, fallback]);
|
|
32
|
+
const [mode, setMode] = React.useState(initial);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (urlOverride === "cards" || urlOverride === "table") {
|
|
35
|
+
setMode(urlOverride);
|
|
36
|
+
}
|
|
37
|
+
}, [urlOverride]);
|
|
38
|
+
const update = React.useCallback(
|
|
39
|
+
(next) => {
|
|
40
|
+
setMode(next);
|
|
41
|
+
writeStoredMode(userKey, next);
|
|
42
|
+
},
|
|
43
|
+
[userKey]
|
|
44
|
+
);
|
|
45
|
+
return [mode, update];
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
useProjectsViewMode
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=useProjectsViewMode.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/staff/lib/timesheets-projects-ui/useProjectsViewMode.ts"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\n\nexport type ProjectsViewMode = 'table' | 'cards'\n\nconst STORAGE_KEY_PREFIX = 'staff.timesheets.projects.viewMode'\n\nfunction storageKey(userKey: string | null | undefined): string {\n return userKey ? `${STORAGE_KEY_PREFIX}:${userKey}` : STORAGE_KEY_PREFIX\n}\n\nfunction readStoredMode(userKey: string | null | undefined): ProjectsViewMode | null {\n if (typeof window === 'undefined') return null\n try {\n const raw = window.localStorage.getItem(storageKey(userKey))\n return raw === 'cards' || raw === 'table' ? raw : null\n } catch {\n return null\n }\n}\n\nfunction writeStoredMode(userKey: string | null | undefined, mode: ProjectsViewMode): void {\n if (typeof window === 'undefined') return\n try {\n window.localStorage.setItem(storageKey(userKey), mode)\n } catch {\n // ignore \u2014 quota errors etc. are non-critical\n }\n}\n\nexport function useProjectsViewMode({\n userKey,\n urlOverride,\n fallback = 'table',\n}: {\n userKey: string | null | undefined\n urlOverride?: string | null\n fallback?: ProjectsViewMode\n}): [ProjectsViewMode, (next: ProjectsViewMode) => void] {\n const initial = React.useMemo<ProjectsViewMode>(() => {\n if (urlOverride === 'cards' || urlOverride === 'table') return urlOverride\n return readStoredMode(userKey) ?? fallback\n }, [urlOverride, userKey, fallback])\n\n const [mode, setMode] = React.useState<ProjectsViewMode>(initial)\n\n React.useEffect(() => {\n if (urlOverride === 'cards' || urlOverride === 'table') {\n setMode(urlOverride)\n }\n }, [urlOverride])\n\n const update = React.useCallback(\n (next: ProjectsViewMode) => {\n setMode(next)\n writeStoredMode(userKey, next)\n },\n [userKey],\n )\n\n return [mode, update]\n}\n"],
|
|
5
|
+
"mappings": ";AAEA,YAAY,WAAW;AAIvB,MAAM,qBAAqB;AAE3B,SAAS,WAAW,SAA4C;AAC9D,SAAO,UAAU,GAAG,kBAAkB,IAAI,OAAO,KAAK;AACxD;AAEA,SAAS,eAAe,SAA6D;AACnF,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,MAAM,OAAO,aAAa,QAAQ,WAAW,OAAO,CAAC;AAC3D,WAAO,QAAQ,WAAW,QAAQ,UAAU,MAAM;AAAA,EACpD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,SAAoC,MAA8B;AACzF,MAAI,OAAO,WAAW,YAAa;AACnC,MAAI;AACF,WAAO,aAAa,QAAQ,WAAW,OAAO,GAAG,IAAI;AAAA,EACvD,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA,WAAW;AACb,GAIyD;AACvD,QAAM,UAAU,MAAM,QAA0B,MAAM;AACpD,QAAI,gBAAgB,WAAW,gBAAgB,QAAS,QAAO;AAC/D,WAAO,eAAe,OAAO,KAAK;AAAA,EACpC,GAAG,CAAC,aAAa,SAAS,QAAQ,CAAC;AAEnC,QAAM,CAAC,MAAM,OAAO,IAAI,MAAM,SAA2B,OAAO;AAEhE,QAAM,UAAU,MAAM;AACpB,QAAI,gBAAgB,WAAW,gBAAgB,SAAS;AACtD,cAAQ,WAAW;AAAA,IACrB;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,SAAS,MAAM;AAAA,IACnB,CAAC,SAA2B;AAC1B,cAAQ,IAAI;AACZ,sBAAgB,SAAS,IAAI;AAAA,IAC/B;AAAA,IACA,CAAC,OAAO;AAAA,EACV;AAEA,SAAO,CAAC,MAAM,MAAM;AACtB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
import { createPortal } from "react-dom";
|
|
5
|
+
import { Button } from "@open-mercato/ui/primitives/button";
|
|
6
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
7
|
+
import { Plus, Search } from "lucide-react";
|
|
8
|
+
import { ProjectColorDot } from "./ProjectColorDot.js";
|
|
9
|
+
const DROPDOWN_WIDTH = 280;
|
|
10
|
+
const DROPDOWN_OFFSET = 4;
|
|
11
|
+
function AddRowDropdown({
|
|
12
|
+
assignedProjects,
|
|
13
|
+
visibleProjectIds,
|
|
14
|
+
canCreateProject,
|
|
15
|
+
onAddProject,
|
|
16
|
+
onCreateProject
|
|
17
|
+
}) {
|
|
18
|
+
const t = useT();
|
|
19
|
+
const [open, setOpen] = React.useState(false);
|
|
20
|
+
const [search, setSearch] = React.useState("");
|
|
21
|
+
const [position, setPosition] = React.useState(null);
|
|
22
|
+
const triggerRef = React.useRef(null);
|
|
23
|
+
const dropdownRef = React.useRef(null);
|
|
24
|
+
const searchInputRef = React.useRef(null);
|
|
25
|
+
const availableProjects = assignedProjects.filter(
|
|
26
|
+
(project) => !visibleProjectIds.has(project.id)
|
|
27
|
+
);
|
|
28
|
+
const filteredProjects = availableProjects.filter(
|
|
29
|
+
(project) => project.name.toLowerCase().includes(search.toLowerCase())
|
|
30
|
+
);
|
|
31
|
+
React.useLayoutEffect(() => {
|
|
32
|
+
if (!open) return;
|
|
33
|
+
const updatePosition = () => {
|
|
34
|
+
const node = triggerRef.current;
|
|
35
|
+
if (!node) return;
|
|
36
|
+
const rect = node.getBoundingClientRect();
|
|
37
|
+
const left = Math.max(8, Math.min(rect.left, window.innerWidth - DROPDOWN_WIDTH - 8));
|
|
38
|
+
setPosition({ top: rect.bottom + DROPDOWN_OFFSET, left });
|
|
39
|
+
};
|
|
40
|
+
updatePosition();
|
|
41
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
42
|
+
window.addEventListener("resize", updatePosition);
|
|
43
|
+
return () => {
|
|
44
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
45
|
+
window.removeEventListener("resize", updatePosition);
|
|
46
|
+
};
|
|
47
|
+
}, [open]);
|
|
48
|
+
React.useEffect(() => {
|
|
49
|
+
if (!open) return;
|
|
50
|
+
function handleClickOutside(event) {
|
|
51
|
+
const target = event.target;
|
|
52
|
+
if (triggerRef.current && !triggerRef.current.contains(target) && dropdownRef.current && !dropdownRef.current.contains(target)) {
|
|
53
|
+
setOpen(false);
|
|
54
|
+
setSearch("");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function handleKeyDown(event) {
|
|
58
|
+
if (event.key === "Escape") {
|
|
59
|
+
setOpen(false);
|
|
60
|
+
setSearch("");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
64
|
+
document.addEventListener("keydown", handleKeyDown);
|
|
65
|
+
return () => {
|
|
66
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
67
|
+
document.removeEventListener("keydown", handleKeyDown);
|
|
68
|
+
};
|
|
69
|
+
}, [open]);
|
|
70
|
+
React.useEffect(() => {
|
|
71
|
+
if (open && searchInputRef.current) {
|
|
72
|
+
searchInputRef.current.focus();
|
|
73
|
+
}
|
|
74
|
+
}, [open]);
|
|
75
|
+
function handleToggle() {
|
|
76
|
+
setOpen((prev) => !prev);
|
|
77
|
+
setSearch("");
|
|
78
|
+
}
|
|
79
|
+
function handleSelectProject(project) {
|
|
80
|
+
onAddProject(project);
|
|
81
|
+
setOpen(false);
|
|
82
|
+
setSearch("");
|
|
83
|
+
}
|
|
84
|
+
function handleCreateProject() {
|
|
85
|
+
onCreateProject();
|
|
86
|
+
setOpen(false);
|
|
87
|
+
setSearch("");
|
|
88
|
+
}
|
|
89
|
+
const dropdown = open && position && typeof document !== "undefined" ? createPortal(
|
|
90
|
+
/* @__PURE__ */ jsxs(
|
|
91
|
+
"div",
|
|
92
|
+
{
|
|
93
|
+
ref: dropdownRef,
|
|
94
|
+
className: "fixed z-50 rounded-lg border bg-popover shadow-lg",
|
|
95
|
+
style: { top: position.top, left: position.left, width: DROPDOWN_WIDTH },
|
|
96
|
+
children: [
|
|
97
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center border-b px-3", children: [
|
|
98
|
+
/* @__PURE__ */ jsx(Search, { className: "h-4 w-4 text-muted-foreground shrink-0" }),
|
|
99
|
+
/* @__PURE__ */ jsx(
|
|
100
|
+
"input",
|
|
101
|
+
{
|
|
102
|
+
ref: searchInputRef,
|
|
103
|
+
type: "text",
|
|
104
|
+
className: "w-full px-3 py-2 text-sm bg-transparent outline-none placeholder:text-muted-foreground",
|
|
105
|
+
placeholder: t("staff.timesheets.my.addRow.searchPlaceholder", "Search by project"),
|
|
106
|
+
value: search,
|
|
107
|
+
onChange: (event) => setSearch(event.target.value)
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
] }),
|
|
111
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-[200px] overflow-y-auto", children: filteredProjects.length === 0 ? /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground text-center", children: t("staff.timesheets.my.addRow.noProjects", "No projects assigned") }) : filteredProjects.map((project) => /* @__PURE__ */ jsxs(
|
|
112
|
+
Button,
|
|
113
|
+
{
|
|
114
|
+
type: "button",
|
|
115
|
+
variant: "ghost",
|
|
116
|
+
className: "w-full justify-start rounded-none px-3 py-2 text-sm cursor-pointer hover:bg-muted transition-colors",
|
|
117
|
+
onClick: () => handleSelectProject(project),
|
|
118
|
+
children: [
|
|
119
|
+
/* @__PURE__ */ jsx(ProjectColorDot, { colorKey: project.color, projectName: project.name, size: "sm" }),
|
|
120
|
+
/* @__PURE__ */ jsx("span", { className: "ml-1.5", children: project.name })
|
|
121
|
+
]
|
|
122
|
+
},
|
|
123
|
+
project.id
|
|
124
|
+
)) }),
|
|
125
|
+
canCreateProject && /* @__PURE__ */ jsxs(
|
|
126
|
+
Button,
|
|
127
|
+
{
|
|
128
|
+
type: "button",
|
|
129
|
+
variant: "ghost",
|
|
130
|
+
className: "w-full justify-start rounded-none px-3 py-2 text-sm text-primary cursor-pointer hover:bg-muted border-t",
|
|
131
|
+
onClick: handleCreateProject,
|
|
132
|
+
children: [
|
|
133
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4 mr-1" }),
|
|
134
|
+
t("staff.timesheets.my.addRow.createProject", "Create a new project")
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
]
|
|
139
|
+
}
|
|
140
|
+
),
|
|
141
|
+
document.body
|
|
142
|
+
) : null;
|
|
143
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
144
|
+
/* @__PURE__ */ jsx("div", { ref: triggerRef, className: "inline-block", children: /* @__PURE__ */ jsxs(
|
|
145
|
+
Button,
|
|
146
|
+
{
|
|
147
|
+
type: "button",
|
|
148
|
+
variant: "ghost",
|
|
149
|
+
className: "flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground cursor-pointer px-3 py-2",
|
|
150
|
+
onClick: handleToggle,
|
|
151
|
+
children: [
|
|
152
|
+
/* @__PURE__ */ jsx(Plus, { className: "h-4 w-4" }),
|
|
153
|
+
t("staff.timesheets.my.addRow.trigger", "Add row")
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
) }),
|
|
157
|
+
dropdown
|
|
158
|
+
] });
|
|
159
|
+
}
|
|
160
|
+
export {
|
|
161
|
+
AddRowDropdown
|
|
162
|
+
};
|
|
163
|
+
//# sourceMappingURL=AddRowDropdown.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/modules/staff/lib/timesheets-ui/AddRowDropdown.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { createPortal } from 'react-dom'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Plus, Search } from 'lucide-react'\nimport { ProjectColorDot } from './ProjectColorDot'\n\ntype ProjectOption = {\n id: string\n name: string\n code: string | null\n color?: string | null\n}\n\ntype AddRowDropdownProps = {\n assignedProjects: ProjectOption[]\n visibleProjectIds: Set<string>\n canCreateProject: boolean\n onAddProject: (project: ProjectOption) => void\n onCreateProject: () => void\n}\n\nconst DROPDOWN_WIDTH = 280\nconst DROPDOWN_OFFSET = 4\n\nexport function AddRowDropdown({\n assignedProjects,\n visibleProjectIds,\n canCreateProject,\n onAddProject,\n onCreateProject,\n}: AddRowDropdownProps) {\n const t = useT()\n const [open, setOpen] = React.useState(false)\n const [search, setSearch] = React.useState('')\n const [position, setPosition] = React.useState<{ top: number; left: number } | null>(null)\n const triggerRef = React.useRef<HTMLDivElement>(null)\n const dropdownRef = React.useRef<HTMLDivElement>(null)\n const searchInputRef = React.useRef<HTMLInputElement>(null)\n\n const availableProjects = assignedProjects.filter(\n (project) => !visibleProjectIds.has(project.id),\n )\n\n const filteredProjects = availableProjects.filter((project) =>\n project.name.toLowerCase().includes(search.toLowerCase()),\n )\n\n React.useLayoutEffect(() => {\n if (!open) return\n const updatePosition = () => {\n const node = triggerRef.current\n if (!node) return\n const rect = node.getBoundingClientRect()\n const left = Math.max(8, Math.min(rect.left, window.innerWidth - DROPDOWN_WIDTH - 8))\n setPosition({ top: rect.bottom + DROPDOWN_OFFSET, left })\n }\n updatePosition()\n window.addEventListener('scroll', updatePosition, true)\n window.addEventListener('resize', updatePosition)\n return () => {\n window.removeEventListener('scroll', updatePosition, true)\n window.removeEventListener('resize', updatePosition)\n }\n }, [open])\n\n React.useEffect(() => {\n if (!open) return\n function handleClickOutside(event: MouseEvent) {\n const target = event.target as Node\n if (\n triggerRef.current && !triggerRef.current.contains(target) &&\n dropdownRef.current && !dropdownRef.current.contains(target)\n ) {\n setOpen(false)\n setSearch('')\n }\n }\n function handleKeyDown(event: KeyboardEvent) {\n if (event.key === 'Escape') {\n setOpen(false)\n setSearch('')\n }\n }\n document.addEventListener('mousedown', handleClickOutside)\n document.addEventListener('keydown', handleKeyDown)\n return () => {\n document.removeEventListener('mousedown', handleClickOutside)\n document.removeEventListener('keydown', handleKeyDown)\n }\n }, [open])\n\n React.useEffect(() => {\n if (open && searchInputRef.current) {\n searchInputRef.current.focus()\n }\n }, [open])\n\n function handleToggle() {\n setOpen((prev) => !prev)\n setSearch('')\n }\n\n function handleSelectProject(project: ProjectOption) {\n onAddProject(project)\n setOpen(false)\n setSearch('')\n }\n\n function handleCreateProject() {\n onCreateProject()\n setOpen(false)\n setSearch('')\n }\n\n const dropdown = open && position && typeof document !== 'undefined' ? createPortal(\n <div\n ref={dropdownRef}\n className=\"fixed z-50 rounded-lg border bg-popover shadow-lg\"\n style={{ top: position.top, left: position.left, width: DROPDOWN_WIDTH }}\n >\n <div className=\"flex items-center border-b px-3\">\n <Search className=\"h-4 w-4 text-muted-foreground shrink-0\" />\n <input\n ref={searchInputRef}\n type=\"text\"\n className=\"w-full px-3 py-2 text-sm bg-transparent outline-none placeholder:text-muted-foreground\"\n placeholder={t('staff.timesheets.my.addRow.searchPlaceholder', 'Search by project')}\n value={search}\n onChange={(event) => setSearch(event.target.value)}\n />\n </div>\n\n <div className=\"max-h-[200px] overflow-y-auto\">\n {filteredProjects.length === 0 ? (\n <div className=\"px-3 py-4 text-sm text-muted-foreground text-center\">\n {t('staff.timesheets.my.addRow.noProjects', 'No projects assigned')}\n </div>\n ) : (\n filteredProjects.map((project) => (\n <Button\n key={project.id}\n type=\"button\"\n variant=\"ghost\"\n className=\"w-full justify-start rounded-none px-3 py-2 text-sm cursor-pointer hover:bg-muted transition-colors\"\n onClick={() => handleSelectProject(project)}\n >\n <ProjectColorDot colorKey={project.color} projectName={project.name} size=\"sm\" />\n <span className=\"ml-1.5\">{project.name}</span>\n </Button>\n ))\n )}\n </div>\n\n {canCreateProject && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"w-full justify-start rounded-none px-3 py-2 text-sm text-primary cursor-pointer hover:bg-muted border-t\"\n onClick={handleCreateProject}\n >\n <Plus className=\"h-4 w-4 mr-1\" />\n {t('staff.timesheets.my.addRow.createProject', 'Create a new project')}\n </Button>\n )}\n </div>,\n document.body,\n ) : null\n\n return (\n <>\n <div ref={triggerRef} className=\"inline-block\">\n <Button\n type=\"button\"\n variant=\"ghost\"\n className=\"flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground cursor-pointer px-3 py-2\"\n onClick={handleToggle}\n >\n <Plus className=\"h-4 w-4\" />\n {t('staff.timesheets.my.addRow.trigger', 'Add row')}\n </Button>\n </div>\n {dropdown}\n </>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|