@open-mercato/core 0.10.1-develop.7717.1.2befe9c634 → 0.10.1-develop.7721.1.b5c4a00a68
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_support_routing_rule/index.js +21 -0
- package/dist/generated/entities/staff_support_routing_rule/index.js.map +7 -0
- package/dist/generated/entities/staff_support_ticket/index.js +37 -0
- package/dist/generated/entities/staff_support_ticket/index.js.map +7 -0
- package/dist/generated/entities/staff_time_project/index.js +2 -0
- package/dist/generated/entities/staff_time_project/index.js.map +2 -2
- package/dist/generated/entities/staff_time_project_member/index.js +2 -0
- package/dist/generated/entities/staff_time_project_member/index.js.map +2 -2
- package/dist/generated/entities/staff_time_task/index.js +4 -0
- package/dist/generated/entities/staff_time_task/index.js.map +2 -2
- package/dist/generated/entities/staff_time_task_comment/index.js +9 -1
- package/dist/generated/entities/staff_time_task_comment/index.js.map +2 -2
- package/dist/generated/entities.ids.generated.js +2 -0
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +38 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/auth.js +1 -0
- package/dist/helpers/integration/auth.js.map +2 -2
- package/dist/helpers/integration/communicationChannelsFixtures.js +20 -0
- package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
- package/dist/modules/catalog/api/bulk-delete/route.js +12 -2
- package/dist/modules/catalog/api/bulk-delete/route.js.map +2 -2
- package/dist/modules/communication_channels/api/post/test-seed/route.js +17 -3
- package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
- package/dist/modules/communication_channels/lib/test-seed.js +38 -5
- package/dist/modules/communication_channels/lib/test-seed.js.map +2 -2
- package/dist/modules/messages/commands/messages.js +2 -3
- package/dist/modules/messages/commands/messages.js.map +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +2 -2
- package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
- package/dist/modules/staff/api/portal/support-tickets/[id]/attachments/route.js +299 -0
- package/dist/modules/staff/api/portal/support-tickets/[id]/attachments/route.js.map +7 -0
- package/dist/modules/staff/api/portal/support-tickets/[id]/messages/route.js +91 -0
- package/dist/modules/staff/api/portal/support-tickets/[id]/messages/route.js.map +7 -0
- package/dist/modules/staff/api/portal/support-tickets/[id]/route.js +146 -0
- package/dist/modules/staff/api/portal/support-tickets/[id]/route.js.map +7 -0
- package/dist/modules/staff/api/portal/support-tickets/options/route.js +60 -0
- package/dist/modules/staff/api/portal/support-tickets/options/route.js.map +7 -0
- package/dist/modules/staff/api/portal/support-tickets/route.js +220 -0
- package/dist/modules/staff/api/portal/support-tickets/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/settings/route.js +7 -1
- package/dist/modules/staff/api/timesheets/settings/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.js +122 -0
- package/dist/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/support-routing-rules/preview/route.js +180 -0
- package/dist/modules/staff/api/timesheets/support-routing-rules/preview/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/support-routing-rules/route.js +147 -0
- package/dist/modules/staff/api/timesheets/support-routing-rules/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/support-tickets/options/route.js +133 -0
- package/dist/modules/staff/api/timesheets/support-tickets/options/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/claim/route.js +33 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/claim/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js +25 -7
- package/dist/modules/staff/api/timesheets/tasks/[id]/comments/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/tasks/[id]/release/route.js +32 -0
- package/dist/modules/staff/api/timesheets/tasks/[id]/release/route.js.map +7 -0
- package/dist/modules/staff/api/timesheets/tasks/route.js +94 -47
- package/dist/modules/staff/api/timesheets/tasks/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js +3 -0
- package/dist/modules/staff/api/timesheets/time-projects/[id]/employees/route.js.map +2 -2
- package/dist/modules/staff/api/timesheets/time-projects/route.js +3 -0
- package/dist/modules/staff/api/timesheets/time-projects/route.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js +1 -0
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +54 -4
- package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js +21 -5
- package/dist/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/settings/page.js +319 -254
- package/dist/modules/staff/backend/staff/time-tracking/settings/page.js.map +2 -2
- package/dist/modules/staff/backend/staff/time-tracking/support/page.js +363 -0
- package/dist/modules/staff/backend/staff/time-tracking/support/page.js.map +7 -0
- package/dist/modules/staff/backend/staff/time-tracking/support/page.meta.js +18 -0
- package/dist/modules/staff/backend/staff/time-tracking/support/page.meta.js.map +7 -0
- package/dist/modules/staff/cli.js +27 -0
- package/dist/modules/staff/cli.js.map +2 -2
- package/dist/modules/staff/commands/index.js +3 -0
- package/dist/modules/staff/commands/index.js.map +2 -2
- package/dist/modules/staff/commands/shared.js +10 -1
- package/dist/modules/staff/commands/shared.js.map +2 -2
- package/dist/modules/staff/commands/support-routing-rules.js +505 -0
- package/dist/modules/staff/commands/support-routing-rules.js.map +7 -0
- package/dist/modules/staff/commands/support-tickets.js +513 -0
- package/dist/modules/staff/commands/support-tickets.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-projects.js +72 -14
- package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-task-assignment.js +270 -0
- package/dist/modules/staff/commands/timesheets-task-assignment.js.map +7 -0
- package/dist/modules/staff/commands/timesheets-task-comments.js +58 -12
- package/dist/modules/staff/commands/timesheets-task-comments.js.map +2 -2
- package/dist/modules/staff/commands/timesheets-tasks.js +91 -9
- package/dist/modules/staff/commands/timesheets-tasks.js.map +3 -3
- package/dist/modules/staff/data/enrichers.js +141 -0
- package/dist/modules/staff/data/enrichers.js.map +2 -2
- package/dist/modules/staff/data/entities.js +143 -2
- package/dist/modules/staff/data/entities.js.map +2 -2
- package/dist/modules/staff/data/extensions.js +8 -0
- package/dist/modules/staff/data/extensions.js.map +2 -2
- package/dist/modules/staff/data/validators.js +34 -5
- package/dist/modules/staff/data/validators.js.map +2 -2
- package/dist/modules/staff/encryption.js +6 -0
- package/dist/modules/staff/encryption.js.map +2 -2
- package/dist/modules/staff/events.js +25 -0
- package/dist/modules/staff/events.js.map +2 -2
- package/dist/modules/staff/events.payloads.js +54 -0
- package/dist/modules/staff/events.payloads.js.map +2 -2
- package/dist/modules/staff/extension-points.js +1 -0
- package/dist/modules/staff/extension-points.js.map +2 -2
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.js +468 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.js +12 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.js +316 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.js +12 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.js +190 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.js.map +7 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.meta.js +19 -0
- package/dist/modules/staff/frontend/[orgSlug]/portal/support/page.meta.js.map +7 -0
- package/dist/modules/staff/index.js +1 -1
- package/dist/modules/staff/index.js.map +2 -2
- package/dist/modules/staff/lib/crud.js +2 -0
- package/dist/modules/staff/lib/crud.js.map +2 -2
- package/dist/modules/staff/lib/support/attachments.js +36 -0
- package/dist/modules/staff/lib/support/attachments.js.map +7 -0
- package/dist/modules/staff/lib/support/dictionaries.js +87 -0
- package/dist/modules/staff/lib/support/dictionaries.js.map +7 -0
- package/dist/modules/staff/lib/support/notifications.js +111 -0
- package/dist/modules/staff/lib/support/notifications.js.map +7 -0
- package/dist/modules/staff/lib/support/portalAttachments.js +100 -0
- package/dist/modules/staff/lib/support/portalAttachments.js.map +7 -0
- package/dist/modules/staff/lib/support/portalBroadcast.js +117 -0
- package/dist/modules/staff/lib/support/portalBroadcast.js.map +7 -0
- package/dist/modules/staff/lib/support/portalRoute.js +99 -0
- package/dist/modules/staff/lib/support/portalRoute.js.map +7 -0
- package/dist/modules/staff/lib/support/portalStatus.js +12 -0
- package/dist/modules/staff/lib/support/portalStatus.js.map +7 -0
- package/dist/modules/staff/lib/support/portalTickets.js +148 -0
- package/dist/modules/staff/lib/support/portalTickets.js.map +7 -0
- package/dist/modules/staff/lib/support/routing.js +81 -0
- package/dist/modules/staff/lib/support/routing.js.map +7 -0
- package/dist/modules/staff/lib/support/routingRuleDraft.js +25 -0
- package/dist/modules/staff/lib/support/routingRuleDraft.js.map +7 -0
- package/dist/modules/staff/lib/support/seedDefaults.js +114 -0
- package/dist/modules/staff/lib/support/seedDefaults.js.map +7 -0
- package/dist/modules/staff/lib/support/supportActivity.js +26 -0
- package/dist/modules/staff/lib/support/supportActivity.js.map +7 -0
- package/dist/modules/staff/lib/support-ui/PortalSupportNotLinked.js +23 -0
- package/dist/modules/staff/lib/support-ui/PortalSupportNotLinked.js.map +7 -0
- package/dist/modules/staff/lib/support-ui/portalAttachmentValidation.js +112 -0
- package/dist/modules/staff/lib/support-ui/portalAttachmentValidation.js.map +7 -0
- package/dist/modules/staff/lib/support-ui/portalPendingUploads.js +45 -0
- package/dist/modules/staff/lib/support-ui/portalPendingUploads.js.map +7 -0
- package/dist/modules/staff/lib/support-ui/portalSupport.js +51 -0
- package/dist/modules/staff/lib/support-ui/portalSupport.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/access.js +3 -39
- package/dist/modules/staff/lib/time-tracking/access.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking/listProjectAccess.js +54 -0
- package/dist/modules/staff/lib/time-tracking/listProjectAccess.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/portalRecipients.js +92 -2
- package/dist/modules/staff/lib/time-tracking/portalRecipients.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking/projectAssignment.js +112 -0
- package/dist/modules/staff/lib/time-tracking/projectAssignment.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/settingKeys.js +14 -0
- package/dist/modules/staff/lib/time-tracking/settingKeys.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking/settings.js +28 -1
- package/dist/modules/staff/lib/time-tracking/settings.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking/taskAssignmentRoute.js +143 -0
- package/dist/modules/staff/lib/time-tracking/taskAssignmentRoute.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking/workRecipients.js +92 -0
- package/dist/modules/staff/lib/time-tracking/workRecipients.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js +32 -3
- package/dist/modules/staff/lib/time-tracking-ui/BoardFilterChips.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js +29 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanBoard.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js +4 -0
- package/dist/modules/staff/lib/time-tracking-ui/KanbanCard.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js +141 -1
- package/dist/modules/staff/lib/time-tracking-ui/ProjectFormSections.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.js +153 -0
- package/dist/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/SupportRequestPanel.js +67 -0
- package/dist/modules/staff/lib/time-tracking-ui/SupportRequestPanel.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js +3 -1
- package/dist/modules/staff/lib/time-tracking-ui/TaskBoardScreen.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js +80 -17
- package/dist/modules/staff/lib/time-tracking-ui/TaskCommentThread.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js +230 -41
- package/dist/modules/staff/lib/time-tracking-ui/TaskDrawer.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js +21 -1
- package/dist/modules/staff/lib/time-tracking-ui/boardDirectory.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js +16 -4
- package/dist/modules/staff/lib/time-tracking-ui/boardFilters.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js +3 -1
- package/dist/modules/staff/lib/time-tracking-ui/kanbanBoardData.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.js +68 -0
- package/dist/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/settingsTabs.js +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/settingsTabs.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/supportTicketData.js +50 -0
- package/dist/modules/staff/lib/time-tracking-ui/supportTicketData.js.map +7 -0
- package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js +13 -1
- package/dist/modules/staff/lib/time-tracking-ui/taskDrawerData.js.map +2 -2
- package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js +36 -2
- package/dist/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.js.map +2 -2
- package/dist/modules/staff/migrations/Migration20261009180543_staff.js +42 -0
- package/dist/modules/staff/migrations/Migration20261009180543_staff.js.map +7 -0
- package/dist/modules/staff/notifications.js +92 -0
- package/dist/modules/staff/notifications.js.map +2 -2
- package/dist/modules/staff/setup.js +6 -2
- package/dist/modules/staff/setup.js.map +2 -2
- package/dist/modules/staff/subscribers/support-portal-comment-created.js +26 -0
- package/dist/modules/staff/subscribers/support-portal-comment-created.js.map +7 -0
- package/dist/modules/staff/subscribers/support-portal-comment-deleted.js +26 -0
- package/dist/modules/staff/subscribers/support-portal-comment-deleted.js.map +7 -0
- package/dist/modules/staff/subscribers/support-portal-comment-updated.js +26 -0
- package/dist/modules/staff/subscribers/support-portal-comment-updated.js.map +7 -0
- package/dist/modules/staff/subscribers/support-portal-status-column-updated.js +24 -0
- package/dist/modules/staff/subscribers/support-portal-status-column-updated.js.map +7 -0
- package/dist/modules/staff/subscribers/support-portal-task-status-changed.js +25 -0
- package/dist/modules/staff/subscribers/support-portal-task-status-changed.js.map +7 -0
- package/dist/modules/staff/subscribers/support-portal-task-updated.js +25 -0
- package/dist/modules/staff/subscribers/support-portal-task-updated.js.map +7 -0
- package/dist/modules/staff/subscribers/support-ticket-created-notification.js +25 -0
- package/dist/modules/staff/subscribers/support-ticket-created-notification.js.map +7 -0
- package/dist/modules/staff/subscribers/support-ticket-customer-replied-notification.js +25 -0
- package/dist/modules/staff/subscribers/support-ticket-customer-replied-notification.js.map +7 -0
- package/dist/modules/staff/subscribers/support-ticket-unnotified-clear.js +26 -0
- package/dist/modules/staff/subscribers/support-ticket-unnotified-clear.js.map +7 -0
- package/dist/modules/staff/subscribers/time-task-assignee-notification.js +83 -0
- package/dist/modules/staff/subscribers/time-task-assignee-notification.js.map +7 -0
- package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.client.js +112 -0
- package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.client.js.map +7 -0
- package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.js +17 -0
- package/dist/modules/staff/widgets/injection/portal-support-tickets/widget.js.map +7 -0
- package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.js +870 -0
- package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.js.map +7 -0
- package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.js +17 -0
- package/dist/modules/staff/widgets/injection/time-tracking-settings-support/widget.js.map +7 -0
- package/dist/modules/staff/widgets/injection-table.js +16 -1
- package/dist/modules/staff/widgets/injection-table.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js +4 -18
- package/dist/modules/wms/components/backend/WmsLocationDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js +4 -18
- package/dist/modules/wms/components/backend/WmsLotDetailPage.js.map +2 -2
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js +4 -18
- package/dist/modules/wms/components/backend/WmsSkuDetailPage.js.map +2 -2
- package/dist/modules/wms/lib/inventoryCsvExport.js +19 -0
- package/dist/modules/wms/lib/inventoryCsvExport.js.map +7 -0
- package/generated/entities/staff_support_routing_rule/index.ts +9 -0
- package/generated/entities/staff_support_ticket/index.ts +17 -0
- package/generated/entities/staff_time_project/index.ts +1 -0
- package/generated/entities/staff_time_project_member/index.ts +1 -0
- package/generated/entities/staff_time_task/index.ts +2 -0
- package/generated/entities/staff_time_task_comment/index.ts +4 -0
- package/generated/entities.ids.generated.ts +2 -0
- package/generated/entity-fields-registry.ts +38 -0
- package/package.json +8 -8
- package/src/helpers/integration/auth.ts +1 -1
- package/src/helpers/integration/communicationChannelsFixtures.ts +60 -2
- package/src/modules/catalog/api/bulk-delete/route.ts +12 -2
- package/src/modules/communication_channels/api/post/test-seed/route.ts +29 -12
- package/src/modules/communication_channels/lib/test-seed.ts +49 -10
- package/src/modules/messages/commands/messages.ts +8 -10
- package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +2 -2
- package/src/modules/staff/AGENTS.md +22 -6
- package/src/modules/staff/api/portal/support-tickets/[id]/attachments/route.ts +327 -0
- package/src/modules/staff/api/portal/support-tickets/[id]/messages/route.ts +94 -0
- package/src/modules/staff/api/portal/support-tickets/[id]/route.ts +160 -0
- package/src/modules/staff/api/portal/support-tickets/options/route.ts +60 -0
- package/src/modules/staff/api/portal/support-tickets/route.ts +253 -0
- package/src/modules/staff/api/timesheets/settings/route.ts +7 -1
- package/src/modules/staff/api/timesheets/support-routing-rules/fallback-project/route.ts +131 -0
- package/src/modules/staff/api/timesheets/support-routing-rules/preview/route.ts +248 -0
- package/src/modules/staff/api/timesheets/support-routing-rules/route.ts +150 -0
- package/src/modules/staff/api/timesheets/support-tickets/options/route.ts +181 -0
- package/src/modules/staff/api/timesheets/tasks/[id]/claim/route.ts +31 -0
- package/src/modules/staff/api/timesheets/tasks/[id]/comments/route.ts +25 -7
- package/src/modules/staff/api/timesheets/tasks/[id]/release/route.ts +30 -0
- package/src/modules/staff/api/timesheets/tasks/route.ts +119 -67
- package/src/modules/staff/api/timesheets/time-projects/[id]/employees/route.ts +3 -0
- package/src/modules/staff/api/timesheets/time-projects/route.ts +3 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/edit/page.tsx +1 -0
- package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +67 -2
- package/src/modules/staff/backend/staff/time-tracking/projects/projectFormConfig.ts +22 -3
- package/src/modules/staff/backend/staff/time-tracking/settings/page.tsx +405 -308
- package/src/modules/staff/backend/staff/time-tracking/support/page.meta.ts +14 -0
- package/src/modules/staff/backend/staff/time-tracking/support/page.tsx +428 -0
- package/src/modules/staff/cli.ts +28 -0
- package/src/modules/staff/commands/index.ts +3 -0
- package/src/modules/staff/commands/shared.ts +22 -1
- package/src/modules/staff/commands/support-routing-rules.ts +595 -0
- package/src/modules/staff/commands/support-tickets.ts +580 -0
- package/src/modules/staff/commands/timesheets-projects.ts +84 -13
- package/src/modules/staff/commands/timesheets-task-assignment.ts +319 -0
- package/src/modules/staff/commands/timesheets-task-comments.ts +70 -15
- package/src/modules/staff/commands/timesheets-tasks.ts +106 -15
- package/src/modules/staff/data/enrichers.ts +203 -0
- package/src/modules/staff/data/entities.ts +133 -2
- package/src/modules/staff/data/extensions.ts +9 -1
- package/src/modules/staff/data/validators.ts +36 -0
- package/src/modules/staff/encryption.ts +6 -0
- package/src/modules/staff/events.payloads.ts +87 -1
- package/src/modules/staff/events.ts +26 -0
- package/src/modules/staff/extension-points.ts +1 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.meta.ts +10 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/support/[id]/page.tsx +553 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/support/new/page.meta.ts +10 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/support/new/page.tsx +346 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/support/page.meta.ts +17 -0
- package/src/modules/staff/frontend/[orgSlug]/portal/support/page.tsx +253 -0
- package/src/modules/staff/i18n/de.json +291 -0
- package/src/modules/staff/i18n/en.json +291 -0
- package/src/modules/staff/i18n/es.json +291 -0
- package/src/modules/staff/i18n/ko.json +291 -0
- package/src/modules/staff/i18n/pl.json +291 -0
- package/src/modules/staff/index.ts +1 -1
- package/src/modules/staff/lib/crud.ts +2 -1
- package/src/modules/staff/lib/support/attachments.ts +43 -0
- package/src/modules/staff/lib/support/dictionaries.ts +120 -0
- package/src/modules/staff/lib/support/notifications.ts +138 -0
- package/src/modules/staff/lib/support/portalAttachments.ts +140 -0
- package/src/modules/staff/lib/support/portalBroadcast.ts +161 -0
- package/src/modules/staff/lib/support/portalRoute.ts +108 -0
- package/src/modules/staff/lib/support/portalStatus.ts +15 -0
- package/src/modules/staff/lib/support/portalTickets.ts +233 -0
- package/src/modules/staff/lib/support/routing.ts +117 -0
- package/src/modules/staff/lib/support/routingRuleDraft.ts +45 -0
- package/src/modules/staff/lib/support/seedDefaults.ts +151 -0
- package/src/modules/staff/lib/support/supportActivity.ts +39 -0
- package/src/modules/staff/lib/support-ui/PortalSupportNotLinked.tsx +20 -0
- package/src/modules/staff/lib/support-ui/portalAttachmentValidation.ts +125 -0
- package/src/modules/staff/lib/support-ui/portalPendingUploads.ts +49 -0
- package/src/modules/staff/lib/support-ui/portalSupport.ts +116 -0
- package/src/modules/staff/lib/time-tracking/access.ts +2 -62
- package/src/modules/staff/lib/time-tracking/listProjectAccess.ts +78 -0
- package/src/modules/staff/lib/time-tracking/portalRecipients.ts +173 -5
- package/src/modules/staff/lib/time-tracking/projectAssignment.ts +172 -0
- package/src/modules/staff/lib/time-tracking/settingKeys.ts +11 -0
- package/src/modules/staff/lib/time-tracking/settings.ts +46 -1
- package/src/modules/staff/lib/time-tracking/taskAssignmentRoute.ts +165 -0
- package/src/modules/staff/lib/time-tracking/workRecipients.ts +183 -0
- package/src/modules/staff/lib/time-tracking-ui/BoardFilterChips.tsx +36 -1
- package/src/modules/staff/lib/time-tracking-ui/KanbanBoard.tsx +30 -0
- package/src/modules/staff/lib/time-tracking-ui/KanbanCard.tsx +9 -0
- package/src/modules/staff/lib/time-tracking-ui/ProjectFormSections.tsx +185 -6
- package/src/modules/staff/lib/time-tracking-ui/SupportAttachmentsSection.tsx +188 -0
- package/src/modules/staff/lib/time-tracking-ui/SupportRequestPanel.tsx +102 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskBoardScreen.tsx +2 -0
- package/src/modules/staff/lib/time-tracking-ui/TaskCommentThread.tsx +105 -22
- package/src/modules/staff/lib/time-tracking-ui/TaskDrawer.tsx +278 -43
- package/src/modules/staff/lib/time-tracking-ui/boardDirectory.ts +21 -0
- package/src/modules/staff/lib/time-tracking-ui/boardFilters.ts +16 -2
- package/src/modules/staff/lib/time-tracking-ui/kanbanBoardData.ts +4 -0
- package/src/modules/staff/lib/time-tracking-ui/projectDefaultAssignee.ts +117 -0
- package/src/modules/staff/lib/time-tracking-ui/settingsTabs.ts +17 -0
- package/src/modules/staff/lib/time-tracking-ui/supportTicketData.ts +71 -0
- package/src/modules/staff/lib/time-tracking-ui/taskDrawerData.ts +15 -0
- package/src/modules/staff/lib/time-tracking-ui/timeTrackingSettingsForm.ts +48 -1
- package/src/modules/staff/migrations/.snapshot-open-mercato.json +714 -0
- package/src/modules/staff/migrations/Migration20261009180543_staff.ts +50 -0
- package/src/modules/staff/notifications.ts +92 -0
- package/src/modules/staff/setup.ts +6 -2
- package/src/modules/staff/subscribers/support-portal-comment-created.ts +35 -0
- package/src/modules/staff/subscribers/support-portal-comment-deleted.ts +35 -0
- package/src/modules/staff/subscribers/support-portal-comment-updated.ts +35 -0
- package/src/modules/staff/subscribers/support-portal-status-column-updated.ts +36 -0
- package/src/modules/staff/subscribers/support-portal-task-status-changed.ts +34 -0
- package/src/modules/staff/subscribers/support-portal-task-updated.ts +34 -0
- package/src/modules/staff/subscribers/support-ticket-created-notification.ts +27 -0
- package/src/modules/staff/subscribers/support-ticket-customer-replied-notification.ts +27 -0
- package/src/modules/staff/subscribers/support-ticket-unnotified-clear.ts +29 -0
- package/src/modules/staff/subscribers/time-task-assignee-notification.ts +102 -0
- package/src/modules/staff/widgets/injection/portal-support-tickets/widget.client.tsx +151 -0
- package/src/modules/staff/widgets/injection/portal-support-tickets/widget.ts +16 -0
- package/src/modules/staff/widgets/injection/time-tracking-settings-support/widget.client.tsx +1058 -0
- package/src/modules/staff/widgets/injection/time-tracking-settings-support/widget.ts +17 -0
- package/src/modules/staff/widgets/injection-table.ts +15 -0
- package/src/modules/wms/components/backend/WmsLocationDetailPage.tsx +4 -20
- package/src/modules/wms/components/backend/WmsLotDetailPage.tsx +4 -20
- package/src/modules/wms/components/backend/WmsSkuDetailPage.tsx +4 -19
- package/src/modules/wms/lib/inventoryCsvExport.ts +18 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { resolveAssignmentState } from './projectTeamAssignment'
|
|
2
|
+
|
|
3
|
+
export const DEFAULT_ASSIGNEE_PAGE_SIZE = 100
|
|
4
|
+
export const DEFAULT_ASSIGNEE_MAX_PAGES = 20
|
|
5
|
+
|
|
6
|
+
export type ProjectMemberRow = {
|
|
7
|
+
id?: unknown
|
|
8
|
+
staffMemberId?: unknown
|
|
9
|
+
staff_member_id?: unknown
|
|
10
|
+
status?: unknown
|
|
11
|
+
assigned_start_date?: unknown
|
|
12
|
+
assignedStartDate?: unknown
|
|
13
|
+
assigned_end_date?: unknown
|
|
14
|
+
assignedEndDate?: unknown
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type ProjectMembershipPage = {
|
|
18
|
+
items: ProjectMemberRow[]
|
|
19
|
+
totalPages: number | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type ProjectMembershipCollection = {
|
|
23
|
+
rows: ProjectMemberRow[]
|
|
24
|
+
truncated: boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type DefaultAssigneeCandidate = {
|
|
28
|
+
staffMemberId: string
|
|
29
|
+
active: boolean
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readString(value: unknown): string | null {
|
|
33
|
+
return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function readMembershipStaffMemberId(row: ProjectMemberRow): string | null {
|
|
37
|
+
return readString(row.staffMemberId) ?? readString(row.staff_member_id)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Whether a membership can still receive a portal ticket as the default assignee —
|
|
42
|
+
* the browser twin of `resolveUsableDefaultAssignee`: an `active` membership inside
|
|
43
|
+
* its assignment window plus the tenant's grace days.
|
|
44
|
+
*/
|
|
45
|
+
export function isUsableDefaultAssigneeMembership(row: ProjectMemberRow, graceDays: number, now: Date = new Date()): boolean {
|
|
46
|
+
if (readString(row.status) !== 'active') return false
|
|
47
|
+
const startDate = readString(row.assignedStartDate) ?? readString(row.assigned_start_date)
|
|
48
|
+
const endDate = readString(row.assignedEndDate) ?? readString(row.assigned_end_date)
|
|
49
|
+
return resolveAssignmentState({ startDate, endDate }, graceDays, now) === 'active'
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type ProjectMembershipPageResponse = {
|
|
53
|
+
ok: boolean
|
|
54
|
+
result?: { items?: unknown; totalPages?: unknown } | null
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Reads one employees page, refusing anything but a successful response with a
|
|
59
|
+
* row list: an error page carries no rows and no total, and reading it as an empty
|
|
60
|
+
* last page would mark every member beyond it as gone.
|
|
61
|
+
*/
|
|
62
|
+
export function readProjectMembershipPage(response: ProjectMembershipPageResponse): ProjectMembershipPage {
|
|
63
|
+
if (!response.ok) throw new Error('[internal] project membership page request failed')
|
|
64
|
+
const items = response.result?.items
|
|
65
|
+
if (!Array.isArray(items)) throw new Error('[internal] project membership page has no rows')
|
|
66
|
+
const totalPages = typeof response.result?.totalPages === 'number' ? response.result.totalPages : null
|
|
67
|
+
const rows = items.filter((item): item is ProjectMemberRow => typeof item === 'object' && item !== null)
|
|
68
|
+
return { items: rows, totalPages }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function collectProjectMemberships(
|
|
72
|
+
fetchPage: (page: number) => Promise<ProjectMembershipPage>,
|
|
73
|
+
options: { pageSize?: number; maxPages?: number } = {},
|
|
74
|
+
): Promise<ProjectMembershipCollection> {
|
|
75
|
+
const pageSize = options.pageSize ?? DEFAULT_ASSIGNEE_PAGE_SIZE
|
|
76
|
+
const maxPages = options.maxPages ?? DEFAULT_ASSIGNEE_MAX_PAGES
|
|
77
|
+
const rows: ProjectMemberRow[] = []
|
|
78
|
+
for (let page = 1; page <= maxPages; page += 1) {
|
|
79
|
+
const result = await fetchPage(page)
|
|
80
|
+
rows.push(...result.items)
|
|
81
|
+
const lastPage = result.totalPages !== null ? page >= result.totalPages : result.items.length < pageSize
|
|
82
|
+
if (lastPage || result.items.length === 0) return { rows, truncated: false }
|
|
83
|
+
}
|
|
84
|
+
return { rows, truncated: true }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function classifyDefaultAssigneeCandidates(
|
|
88
|
+
rows: ProjectMemberRow[],
|
|
89
|
+
graceDays: number,
|
|
90
|
+
now: Date = new Date(),
|
|
91
|
+
): DefaultAssigneeCandidate[] {
|
|
92
|
+
const byMember = new Map<string, boolean>()
|
|
93
|
+
for (const row of rows) {
|
|
94
|
+
const staffMemberId = readMembershipStaffMemberId(row)
|
|
95
|
+
if (!staffMemberId) continue
|
|
96
|
+
const active = isUsableDefaultAssigneeMembership(row, graceDays, now)
|
|
97
|
+
byMember.set(staffMemberId, (byMember.get(staffMemberId) ?? false) || active)
|
|
98
|
+
}
|
|
99
|
+
return Array.from(byMember, ([staffMemberId, active]) => ({ staffMemberId, active }))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function chunkIds(ids: string[], size: number = DEFAULT_ASSIGNEE_PAGE_SIZE): string[][] {
|
|
103
|
+
const batches: string[][] = []
|
|
104
|
+
for (let index = 0; index < ids.length; index += size) batches.push(ids.slice(index, index + size))
|
|
105
|
+
return batches
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function resolveSelectedDefaultAssignee(
|
|
109
|
+
candidates: DefaultAssigneeCandidate[],
|
|
110
|
+
value: string | null,
|
|
111
|
+
truncated: boolean,
|
|
112
|
+
): { candidate: DefaultAssigneeCandidate | null; unusable: boolean } {
|
|
113
|
+
if (!value) return { candidate: null, unusable: false }
|
|
114
|
+
const candidate = candidates.find((entry) => entry.staffMemberId === value) ?? null
|
|
115
|
+
if (candidate) return { candidate, unusable: !candidate.active }
|
|
116
|
+
return { candidate: null, unusable: !truncated }
|
|
117
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { TimeTrackingSettings } from '../time-tracking/settings'
|
|
2
|
+
|
|
3
|
+
export const TIME_TRACKING_SETTINGS_GENERAL_TAB = 'general'
|
|
4
|
+
export const TIME_TRACKING_SETTINGS_TAB_PARAM = 'tab'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Context of the `staff.time_tracking.settings:tabs` spot. A tab owns its saves and does
|
|
8
|
+
* not sit under the page's Save bar. When it writes the settings record itself it builds
|
|
9
|
+
* the body from `settings` (the last saved record, never the page's unsaved draft) and
|
|
10
|
+
* hands the response to `onSettingsSaved`, which rebases the page draft onto it.
|
|
11
|
+
*/
|
|
12
|
+
export type TimeTrackingSettingsTabContext = {
|
|
13
|
+
moduleId: string
|
|
14
|
+
canManage: boolean
|
|
15
|
+
settings: TimeTrackingSettings
|
|
16
|
+
onSettingsSaved: (settings: TimeTrackingSettings) => void
|
|
17
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { StatusBadgeVariant } from '@open-mercato/ui/primitives/status-badge'
|
|
2
|
+
import type { BoardApiRow } from './kanbanBoardData'
|
|
3
|
+
|
|
4
|
+
export type SupportPortalStatus = 'received' | 'in_progress' | 'resolved'
|
|
5
|
+
|
|
6
|
+
export type SupportTicketView = {
|
|
7
|
+
id: string
|
|
8
|
+
supportReference: string
|
|
9
|
+
categoryValue: string
|
|
10
|
+
categoryLabel: string
|
|
11
|
+
routedVia: 'category' | 'fallback'
|
|
12
|
+
portalStatus: SupportPortalStatus
|
|
13
|
+
customerName: string | null
|
|
14
|
+
customerKind: string | null
|
|
15
|
+
reporterName: string | null
|
|
16
|
+
reportedByCustomerUserId: string | null
|
|
17
|
+
unnotifiedAt: string | null
|
|
18
|
+
requestSubject: string | null
|
|
19
|
+
requestBody: string | null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const SUPPORT_PORTAL_STATUS_VARIANT: Record<SupportPortalStatus, StatusBadgeVariant> = {
|
|
23
|
+
received: 'info',
|
|
24
|
+
in_progress: 'warning',
|
|
25
|
+
resolved: 'success',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
29
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function readText(source: Record<string, unknown> | null | undefined, key: string): string | null {
|
|
33
|
+
const value = source?.[key]
|
|
34
|
+
return typeof value === 'string' && value.length > 0 ? value : null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function readPortalStatus(value: unknown): SupportPortalStatus {
|
|
38
|
+
return value === 'resolved' || value === 'in_progress' ? value : 'received'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** Reads the `_staffSupport.ticket` enrichment off a tasks API row. Internal tasks answer `null`. */
|
|
42
|
+
export function readSupportTicket(row: BoardApiRow | null | undefined): SupportTicketView | null {
|
|
43
|
+
if (!row) return null
|
|
44
|
+
const enrichment = (row as Record<string, unknown>)._staffSupport
|
|
45
|
+
if (!isRecord(enrichment)) return null
|
|
46
|
+
const ticket = enrichment.ticket
|
|
47
|
+
if (!isRecord(ticket)) return null
|
|
48
|
+
const id = readText(ticket, 'id')
|
|
49
|
+
const supportReference = readText(ticket, 'supportReference')
|
|
50
|
+
if (!id || !supportReference) return null
|
|
51
|
+
const category = isRecord(ticket.category) ? ticket.category : null
|
|
52
|
+
const customer = isRecord(ticket.customerSnapshot) ? ticket.customerSnapshot : null
|
|
53
|
+
const request = isRecord(ticket.customerRequest) ? ticket.customerRequest : null
|
|
54
|
+
return {
|
|
55
|
+
id,
|
|
56
|
+
supportReference,
|
|
57
|
+
categoryValue: readText(category, 'value') ?? '',
|
|
58
|
+
categoryLabel: readText(category, 'label') ?? readText(category, 'value') ?? '',
|
|
59
|
+
routedVia: ticket.routedVia === 'category' ? 'category' : 'fallback',
|
|
60
|
+
portalStatus: readPortalStatus(ticket.portalStatus),
|
|
61
|
+
customerName: readText(customer, 'displayName'),
|
|
62
|
+
customerKind: readText(customer, 'kind'),
|
|
63
|
+
reporterName: readText(customer, 'reporterDisplayName'),
|
|
64
|
+
reportedByCustomerUserId: readText(ticket, 'reportedByCustomerUserId'),
|
|
65
|
+
unnotifiedAt: readText(ticket, 'unnotifiedAt'),
|
|
66
|
+
requestSubject: readText(request, 'subject'),
|
|
67
|
+
requestBody: typeof request?.body === 'string' ? (request.body as string) : null,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const SUPPORT_ACTIVITY_EVENT = 'staff.support_ticket.activity_recorded'
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
import { formatDuration } from '../time-tracking/duration'
|
|
16
16
|
import { readNumber, readString, type BoardApiRow, type BoardStatus } from './kanbanBoardData'
|
|
17
17
|
|
|
18
|
+
export const TASK_DRAWER_QUERY_ROOT = ['staff', 'time-tracking', 'task-drawer'] as const
|
|
19
|
+
|
|
18
20
|
export type DrawerComment = {
|
|
19
21
|
id: string
|
|
20
22
|
body: string
|
|
@@ -22,6 +24,9 @@ export type DrawerComment = {
|
|
|
22
24
|
authorName: string | null
|
|
23
25
|
authorEmail: string | null
|
|
24
26
|
createdAt: string | null
|
|
27
|
+
visibility: 'internal' | 'customer'
|
|
28
|
+
authorKind: 'staff' | 'customer'
|
|
29
|
+
updatedAt: string | null
|
|
25
30
|
}
|
|
26
31
|
|
|
27
32
|
export type DrawerEntry = {
|
|
@@ -57,6 +62,9 @@ export function toDrawerComment(row: BoardApiRow): DrawerComment | null {
|
|
|
57
62
|
authorName: readString(row, 'authorName', 'author_name'),
|
|
58
63
|
authorEmail: readString(row, 'authorEmail', 'author_email'),
|
|
59
64
|
createdAt: readString(row, 'createdAt', 'created_at'),
|
|
65
|
+
visibility: readString(row, 'visibility') === 'customer' ? 'customer' : 'internal',
|
|
66
|
+
authorKind: readString(row, 'authorKind', 'author_kind') === 'customer' ? 'customer' : 'staff',
|
|
67
|
+
updatedAt: readString(row, 'updatedAt', 'updated_at'),
|
|
60
68
|
}
|
|
61
69
|
}
|
|
62
70
|
|
|
@@ -192,3 +200,10 @@ export function buildEntryClocks({ date, startClock, endClock, minutes }: EntryC
|
|
|
192
200
|
endedAt: `${date}T${minutesToClock(resolvedEnd)}`,
|
|
193
201
|
}
|
|
194
202
|
}
|
|
203
|
+
|
|
204
|
+
export const TASK_ASSIGNMENT_CHANGED_EVENT = 'staff.timesheets.time_task.assignee_changed'
|
|
205
|
+
|
|
206
|
+
export function isAssignmentEventForTask(payload: unknown, taskId: string): boolean {
|
|
207
|
+
if (!taskId || typeof payload !== 'object' || payload === null) return false
|
|
208
|
+
return (payload as { id?: unknown }).id === taskId
|
|
209
|
+
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { formatDuration } from '../time-tracking/duration'
|
|
18
18
|
import { roundMinutes, type RoundingSettings, type RoundingUnitMinutes } from '../time-tracking/rounding'
|
|
19
|
-
import { contributedTimeTrackingSettingKeys } from '../time-tracking/settingKeys'
|
|
19
|
+
import { DEFAULT_SUPPORT_REFERENCE_PREFIX, contributedTimeTrackingSettingKeys } from '../time-tracking/settingKeys'
|
|
20
20
|
import { readTimeTrackingSettingValue, type TimeTrackingSettings } from '../time-tracking/settings'
|
|
21
21
|
|
|
22
22
|
export const ROUNDING_UNIT_OPTIONS: readonly RoundingUnitMinutes[] = [0, 5, 10, 15]
|
|
@@ -65,6 +65,8 @@ export type TimeTrackingSettingsDraft = {
|
|
|
65
65
|
warningsOverlap: boolean
|
|
66
66
|
warningsRunningTimer: boolean
|
|
67
67
|
assignmentGraceDaysText: string
|
|
68
|
+
/** Edited on the Support settings tab; carried through so this page's Save never resets it. */
|
|
69
|
+
supportReferencePrefix: string
|
|
68
70
|
/**
|
|
69
71
|
* EP-42 — every contributed setting key, by its `<group>.<key>` id, carried through
|
|
70
72
|
* the draft untouched so the page's own Save round-trips a contribution it knows
|
|
@@ -86,6 +88,7 @@ export function toSettingsDraft(settings: TimeTrackingSettings): TimeTrackingSet
|
|
|
86
88
|
warningsOverlap: settings.warnings.overlap,
|
|
87
89
|
warningsRunningTimer: settings.warnings.runningTimer,
|
|
88
90
|
assignmentGraceDaysText: String(settings.access.assignmentGraceDays),
|
|
91
|
+
supportReferencePrefix: settings.support?.referencePrefix ?? DEFAULT_SUPPORT_REFERENCE_PREFIX,
|
|
89
92
|
contributed: Object.fromEntries(
|
|
90
93
|
contributedTimeTrackingSettingKeys().map((entry) => [
|
|
91
94
|
entry.id,
|
|
@@ -139,6 +142,7 @@ export function toSettingsPayload(draft: TimeTrackingSettingsDraft): TimeTrackin
|
|
|
139
142
|
targets: { dailyHours },
|
|
140
143
|
warnings: { overlap: draft.warningsOverlap, runningTimer: draft.warningsRunningTimer },
|
|
141
144
|
access: { assignmentGraceDays },
|
|
145
|
+
support: { referencePrefix: draft.supportReferencePrefix },
|
|
142
146
|
}
|
|
143
147
|
for (const entry of contributedTimeTrackingSettingKeys()) {
|
|
144
148
|
const group = (payload[entry.group] ?? {}) as Record<string, unknown>
|
|
@@ -148,6 +152,49 @@ export function toSettingsPayload(draft: TimeTrackingSettingsDraft): TimeTrackin
|
|
|
148
152
|
return payload
|
|
149
153
|
}
|
|
150
154
|
|
|
155
|
+
/**
|
|
156
|
+
* A settings tab that saves the record itself moves the stored baseline under the
|
|
157
|
+
* page's draft. Rebase the draft onto the new record: a field the user has not touched
|
|
158
|
+
* takes the saved value, an edited field keeps the edit, so the page's Save neither
|
|
159
|
+
* reverts the tab's write nor drops pending changes.
|
|
160
|
+
*/
|
|
161
|
+
export function rebaseSettingsDraft(
|
|
162
|
+
draft: TimeTrackingSettingsDraft,
|
|
163
|
+
previousBaseline: TimeTrackingSettingsDraft,
|
|
164
|
+
nextBaseline: TimeTrackingSettingsDraft,
|
|
165
|
+
): TimeTrackingSettingsDraft {
|
|
166
|
+
const pick = <TValue>(current: TValue, previous: TValue, next: TValue): TValue =>
|
|
167
|
+
Object.is(current, previous) ? next : current
|
|
168
|
+
const contributed: Record<string, unknown> = { ...nextBaseline.contributed }
|
|
169
|
+
for (const [id, value] of Object.entries(draft.contributed)) {
|
|
170
|
+
contributed[id] = pick(value, previousBaseline.contributed[id], nextBaseline.contributed[id])
|
|
171
|
+
}
|
|
172
|
+
return {
|
|
173
|
+
roundingUnitMinutes: pick(draft.roundingUnitMinutes, previousBaseline.roundingUnitMinutes, nextBaseline.roundingUnitMinutes),
|
|
174
|
+
roundingDirection: pick(draft.roundingDirection, previousBaseline.roundingDirection, nextBaseline.roundingDirection),
|
|
175
|
+
defaultsBillable: pick(draft.defaultsBillable, previousBaseline.defaultsBillable, nextBaseline.defaultsBillable),
|
|
176
|
+
defaultsChainStartFromPreviousEnd: pick(
|
|
177
|
+
draft.defaultsChainStartFromPreviousEnd,
|
|
178
|
+
previousBaseline.defaultsChainStartFromPreviousEnd,
|
|
179
|
+
nextBaseline.defaultsChainStartFromPreviousEnd,
|
|
180
|
+
),
|
|
181
|
+
dailyHoursText: pick(draft.dailyHoursText, previousBaseline.dailyHoursText, nextBaseline.dailyHoursText),
|
|
182
|
+
warningsOverlap: pick(draft.warningsOverlap, previousBaseline.warningsOverlap, nextBaseline.warningsOverlap),
|
|
183
|
+
warningsRunningTimer: pick(draft.warningsRunningTimer, previousBaseline.warningsRunningTimer, nextBaseline.warningsRunningTimer),
|
|
184
|
+
assignmentGraceDaysText: pick(
|
|
185
|
+
draft.assignmentGraceDaysText,
|
|
186
|
+
previousBaseline.assignmentGraceDaysText,
|
|
187
|
+
nextBaseline.assignmentGraceDaysText,
|
|
188
|
+
),
|
|
189
|
+
supportReferencePrefix: pick(
|
|
190
|
+
draft.supportReferencePrefix,
|
|
191
|
+
previousBaseline.supportReferencePrefix,
|
|
192
|
+
nextBaseline.supportReferencePrefix,
|
|
193
|
+
),
|
|
194
|
+
contributed,
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
151
198
|
export function isSettingsDraftDirty(
|
|
152
199
|
draft: TimeTrackingSettingsDraft,
|
|
153
200
|
baseline: TimeTrackingSettingsDraft,
|