@hed-hog/operations 0.0.330 → 0.0.332
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/README.md +5 -5
- package/dist/controllers/operations-collaborators.controller.d.ts +58 -213
- package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -1
- package/dist/controllers/operations-collaborators.controller.js +100 -0
- package/dist/controllers/operations-collaborators.controller.js.map +1 -1
- package/dist/controllers/operations-contracts.controller.d.ts +6 -6
- package/dist/controllers/operations-projects.controller.d.ts +25 -0
- package/dist/controllers/operations-projects.controller.d.ts.map +1 -1
- package/dist/controllers/operations-projects.controller.js +48 -0
- package/dist/controllers/operations-projects.controller.js.map +1 -1
- package/dist/controllers/operations-reports.controller.d.ts +1 -1
- package/dist/controllers/operations-tasks.controller.d.ts +34 -9
- package/dist/controllers/operations-tasks.controller.d.ts.map +1 -1
- package/dist/controllers/operations-tasks.controller.js +43 -32
- package/dist/controllers/operations-tasks.controller.js.map +1 -1
- package/dist/controllers/operations-timesheets.controller.d.ts +9 -9
- package/dist/dashboard/components/DashboardLayout.d.ts +30 -0
- package/dist/dashboard/components/DashboardLayout.d.ts.map +1 -0
- package/dist/dashboard/components/DashboardLayout.js +87 -0
- package/dist/dashboard/components/DashboardLayout.js.map +1 -0
- package/dist/dashboard/components/widget-registry.d.ts +23 -0
- package/dist/dashboard/components/widget-registry.d.ts.map +1 -0
- package/dist/dashboard/components/widget-registry.js +245 -0
- package/dist/dashboard/components/widget-registry.js.map +1 -0
- package/dist/dashboard/hooks/useDashboardData.d.ts +20 -0
- package/dist/dashboard/hooks/useDashboardData.d.ts.map +1 -0
- package/dist/dashboard/hooks/useDashboardData.js +24 -0
- package/dist/dashboard/hooks/useDashboardData.js.map +1 -0
- package/dist/dashboard/types/widgets.types.d.ts +233 -0
- package/dist/dashboard/types/widgets.types.d.ts.map +1 -0
- package/dist/dashboard/types/widgets.types.js +6 -0
- package/dist/dashboard/types/widgets.types.js.map +1 -0
- package/dist/dashboard/widgets/CapacityDistribution.d.ts +23 -0
- package/dist/dashboard/widgets/CapacityDistribution.d.ts.map +1 -0
- package/dist/dashboard/widgets/CapacityDistribution.js +11 -0
- package/dist/dashboard/widgets/CapacityDistribution.js.map +1 -0
- package/dist/dashboard/widgets/EffortByProject.d.ts +22 -0
- package/dist/dashboard/widgets/EffortByProject.d.ts.map +1 -0
- package/dist/dashboard/widgets/EffortByProject.js +11 -0
- package/dist/dashboard/widgets/EffortByProject.js.map +1 -0
- package/dist/dashboard/widgets/HeadcountByArea.d.ts +24 -0
- package/dist/dashboard/widgets/HeadcountByArea.d.ts.map +1 -0
- package/dist/dashboard/widgets/HeadcountByArea.js +11 -0
- package/dist/dashboard/widgets/HeadcountByArea.js.map +1 -0
- package/dist/dashboard/widgets/ManagedProjectsStatus.d.ts +18 -0
- package/dist/dashboard/widgets/ManagedProjectsStatus.d.ts.map +1 -0
- package/dist/dashboard/widgets/ManagedProjectsStatus.js +12 -0
- package/dist/dashboard/widgets/ManagedProjectsStatus.js.map +1 -0
- package/dist/dashboard/widgets/MyHoursPeriodKpi.d.ts +22 -0
- package/dist/dashboard/widgets/MyHoursPeriodKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyHoursPeriodKpi.js +12 -0
- package/dist/dashboard/widgets/MyHoursPeriodKpi.js.map +1 -0
- package/dist/dashboard/widgets/MyOpenRequestsKpi.d.ts +19 -0
- package/dist/dashboard/widgets/MyOpenRequestsKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyOpenRequestsKpi.js +17 -0
- package/dist/dashboard/widgets/MyOpenRequestsKpi.js.map +1 -0
- package/dist/dashboard/widgets/MyPendingRequestsList.d.ts +23 -0
- package/dist/dashboard/widgets/MyPendingRequestsList.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyPendingRequestsList.js +14 -0
- package/dist/dashboard/widgets/MyPendingRequestsList.js.map +1 -0
- package/dist/dashboard/widgets/MyProjectAllocationsKpi.d.ts +22 -0
- package/dist/dashboard/widgets/MyProjectAllocationsKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyProjectAllocationsKpi.js +11 -0
- package/dist/dashboard/widgets/MyProjectAllocationsKpi.js.map +1 -0
- package/dist/dashboard/widgets/MyQuickActions.d.ts +23 -0
- package/dist/dashboard/widgets/MyQuickActions.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyQuickActions.js +18 -0
- package/dist/dashboard/widgets/MyQuickActions.js.map +1 -0
- package/dist/dashboard/widgets/MyRelevantDeadlines.d.ts +23 -0
- package/dist/dashboard/widgets/MyRelevantDeadlines.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyRelevantDeadlines.js +22 -0
- package/dist/dashboard/widgets/MyRelevantDeadlines.js.map +1 -0
- package/dist/dashboard/widgets/MyTimesheetStatusKpi.d.ts +17 -0
- package/dist/dashboard/widgets/MyTimesheetStatusKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyTimesheetStatusKpi.js +11 -0
- package/dist/dashboard/widgets/MyTimesheetStatusKpi.js.map +1 -0
- package/dist/dashboard/widgets/MyWeeklyJourney.d.ts +21 -0
- package/dist/dashboard/widgets/MyWeeklyJourney.d.ts.map +1 -0
- package/dist/dashboard/widgets/MyWeeklyJourney.js +19 -0
- package/dist/dashboard/widgets/MyWeeklyJourney.js.map +1 -0
- package/dist/dashboard/widgets/PortfolioCostsKpi.d.ts +19 -0
- package/dist/dashboard/widgets/PortfolioCostsKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/PortfolioCostsKpi.js +12 -0
- package/dist/dashboard/widgets/PortfolioCostsKpi.js.map +1 -0
- package/dist/dashboard/widgets/PortfolioEffortKpi.d.ts +18 -0
- package/dist/dashboard/widgets/PortfolioEffortKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/PortfolioEffortKpi.js +8 -0
- package/dist/dashboard/widgets/PortfolioEffortKpi.js.map +1 -0
- package/dist/dashboard/widgets/PortfolioProjectsKpi.d.ts +22 -0
- package/dist/dashboard/widgets/PortfolioProjectsKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/PortfolioProjectsKpi.js +56 -0
- package/dist/dashboard/widgets/PortfolioProjectsKpi.js.map +1 -0
- package/dist/dashboard/widgets/PortfolioRiskKpi.d.ts +19 -0
- package/dist/dashboard/widgets/PortfolioRiskKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/PortfolioRiskKpi.js +11 -0
- package/dist/dashboard/widgets/PortfolioRiskKpi.js.map +1 -0
- package/dist/dashboard/widgets/ProjectStatusOverview.d.ts +19 -0
- package/dist/dashboard/widgets/ProjectStatusOverview.d.ts.map +1 -0
- package/dist/dashboard/widgets/ProjectStatusOverview.js +18 -0
- package/dist/dashboard/widgets/ProjectStatusOverview.js.map +1 -0
- package/dist/dashboard/widgets/StrategicDeadlines.d.ts +24 -0
- package/dist/dashboard/widgets/StrategicDeadlines.d.ts.map +1 -0
- package/dist/dashboard/widgets/StrategicDeadlines.js +22 -0
- package/dist/dashboard/widgets/StrategicDeadlines.js.map +1 -0
- package/dist/dashboard/widgets/TeamApprovalQueue.d.ts +24 -0
- package/dist/dashboard/widgets/TeamApprovalQueue.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamApprovalQueue.js +12 -0
- package/dist/dashboard/widgets/TeamApprovalQueue.js.map +1 -0
- package/dist/dashboard/widgets/TeamCapacityKpi.d.ts +18 -0
- package/dist/dashboard/widgets/TeamCapacityKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamCapacityKpi.js +19 -0
- package/dist/dashboard/widgets/TeamCapacityKpi.js.map +1 -0
- package/dist/dashboard/widgets/TeamHeadcountKpi.d.ts +22 -0
- package/dist/dashboard/widgets/TeamHeadcountKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamHeadcountKpi.js +56 -0
- package/dist/dashboard/widgets/TeamHeadcountKpi.js.map +1 -0
- package/dist/dashboard/widgets/TeamHoursKpi.d.ts +19 -0
- package/dist/dashboard/widgets/TeamHoursKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamHoursKpi.js +13 -0
- package/dist/dashboard/widgets/TeamHoursKpi.js.map +1 -0
- package/dist/dashboard/widgets/TeamPendingApprovalsKpi.d.ts +20 -0
- package/dist/dashboard/widgets/TeamPendingApprovalsKpi.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamPendingApprovalsKpi.js +11 -0
- package/dist/dashboard/widgets/TeamPendingApprovalsKpi.js.map +1 -0
- package/dist/dashboard/widgets/TeamUtilizationOverview.d.ts +18 -0
- package/dist/dashboard/widgets/TeamUtilizationOverview.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamUtilizationOverview.js +17 -0
- package/dist/dashboard/widgets/TeamUtilizationOverview.js.map +1 -0
- package/dist/dashboard/widgets/TeamWorkloadAlerts.d.ts +24 -0
- package/dist/dashboard/widgets/TeamWorkloadAlerts.d.ts.map +1 -0
- package/dist/dashboard/widgets/TeamWorkloadAlerts.js +19 -0
- package/dist/dashboard/widgets/TeamWorkloadAlerts.js.map +1 -0
- package/dist/dashboard/widgets/index.d.ts +24 -0
- package/dist/dashboard/widgets/index.d.ts.map +1 -0
- package/dist/dashboard/widgets/index.js +54 -0
- package/dist/dashboard/widgets/index.js.map +1 -0
- package/dist/dto/create-collaborator-invoice.dto.d.ts +11 -0
- package/dist/dto/create-collaborator-invoice.dto.d.ts.map +1 -0
- package/dist/dto/create-collaborator-invoice.dto.js +55 -0
- package/dist/dto/create-collaborator-invoice.dto.js.map +1 -0
- package/dist/dto/create-collaborator-payment.dto.d.ts +10 -0
- package/dist/dto/create-collaborator-payment.dto.d.ts.map +1 -0
- package/dist/dto/create-collaborator-payment.dto.js +50 -0
- package/dist/dto/create-collaborator-payment.dto.js.map +1 -0
- package/dist/dto/create-collaborator.dto.d.ts +0 -1
- package/dist/dto/create-collaborator.dto.d.ts.map +1 -1
- package/dist/dto/create-collaborator.dto.js +0 -6
- package/dist/dto/create-collaborator.dto.js.map +1 -1
- package/dist/dto/list-collaborator-invoice.dto.d.ts +4 -0
- package/dist/dto/list-collaborator-invoice.dto.d.ts.map +1 -0
- package/dist/dto/list-collaborator-invoice.dto.js +8 -0
- package/dist/dto/list-collaborator-invoice.dto.js.map +1 -0
- package/dist/dto/list-collaborator-payment.dto.d.ts +4 -0
- package/dist/dto/list-collaborator-payment.dto.d.ts.map +1 -0
- package/dist/dto/list-collaborator-payment.dto.js +8 -0
- package/dist/dto/list-collaborator-payment.dto.js.map +1 -0
- package/dist/dto/update-collaborator-invoice.dto.d.ts +6 -0
- package/dist/dto/update-collaborator-invoice.dto.d.ts.map +1 -0
- package/dist/dto/update-collaborator-invoice.dto.js +9 -0
- package/dist/dto/update-collaborator-invoice.dto.js.map +1 -0
- package/dist/dto/update-collaborator-payment.dto.d.ts +6 -0
- package/dist/dto/update-collaborator-payment.dto.d.ts.map +1 -0
- package/dist/dto/update-collaborator-payment.dto.js +9 -0
- package/dist/dto/update-collaborator-payment.dto.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/operations.controller.d.ts +42 -0
- package/dist/operations.controller.d.ts.map +1 -1
- package/dist/operations.service.d.ts +258 -268
- package/dist/operations.service.d.ts.map +1 -1
- package/dist/operations.service.js +2381 -1341
- package/dist/operations.service.js.map +1 -1
- package/dist/operations.service.spec.js +345 -174
- package/dist/operations.service.spec.js.map +1 -1
- package/hedhog/data/dashboard_component.yaml +66 -0
- package/hedhog/data/dashboard_item.yaml +25 -25
- package/hedhog/data/menu.yaml +27 -8
- package/hedhog/data/route.yaml +133 -0
- package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +78 -102
- package/hedhog/frontend/app/_components/collaborator-invoices-tab.tsx.ejs +443 -0
- package/hedhog/frontend/app/_components/collaborator-payment-history-tab.tsx.ejs +429 -0
- package/hedhog/frontend/app/_components/collaborator-picker.tsx.ejs +158 -0
- package/hedhog/frontend/app/_components/my-project-summary-screen.tsx.ejs +247 -50
- package/hedhog/frontend/app/_components/project-assignments-tab.tsx.ejs +643 -450
- package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +992 -431
- package/hedhog/frontend/app/_components/project-file-attachments.tsx.ejs +371 -0
- package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +558 -386
- package/hedhog/frontend/app/_components/task-detail-sheet.tsx.ejs +383 -157
- package/hedhog/frontend/app/_components/task-file-attachments.tsx.ejs +4 -1
- package/hedhog/frontend/app/_components/task-form-fields.tsx.ejs +406 -0
- package/hedhog/frontend/app/_components/task-form-sheet.tsx.ejs +629 -784
- package/hedhog/frontend/app/_components/task-info-display.tsx.ejs +137 -0
- package/hedhog/frontend/app/_components/timesheet-entry-create-sheet.tsx.ejs +306 -0
- package/hedhog/frontend/app/_lib/api.ts.ejs +155 -0
- package/hedhog/frontend/app/_lib/types.ts.ejs +62 -0
- package/hedhog/frontend/app/_lib/utils/format.ts.ejs +0 -2
- package/hedhog/frontend/app/_lib/utils/task-ui.ts.ejs +61 -0
- package/hedhog/frontend/app/approvals/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/collaborator-types/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/collaborators/page.tsx.ejs +59 -8
- package/hedhog/frontend/app/contracts/page.tsx.ejs +29 -8
- package/hedhog/frontend/app/dashboard/widgets/CapacityDistribution.tsx.ejs +84 -0
- package/hedhog/frontend/app/dashboard/widgets/EffortByProject.tsx.ejs +85 -0
- package/hedhog/frontend/app/dashboard/widgets/HeadcountByArea.tsx.ejs +101 -0
- package/hedhog/frontend/app/dashboard/widgets/ManagedProjectsStatus.tsx.ejs +113 -0
- package/hedhog/frontend/app/dashboard/widgets/MyHoursPeriodKpi.tsx.ejs +87 -0
- package/hedhog/frontend/app/dashboard/widgets/MyOpenRequestsKpi.tsx.ejs +97 -0
- package/hedhog/frontend/app/dashboard/widgets/MyPendingRequestsList.tsx.ejs +99 -0
- package/hedhog/frontend/app/dashboard/widgets/MyProjectAllocationsKpi.tsx.ejs +78 -0
- package/hedhog/frontend/app/dashboard/widgets/MyQuickActions.tsx.ejs +130 -0
- package/hedhog/frontend/app/dashboard/widgets/MyRelevantDeadlines.tsx.ejs +144 -0
- package/hedhog/frontend/app/dashboard/widgets/MyTimesheetStatusKpi.tsx.ejs +78 -0
- package/hedhog/frontend/app/dashboard/widgets/MyWeeklyJourney.tsx.ejs +99 -0
- package/hedhog/frontend/app/dashboard/widgets/PortfolioCostsKpi.tsx.ejs +112 -0
- package/hedhog/frontend/app/dashboard/widgets/PortfolioEffortKpi.tsx.ejs +93 -0
- package/hedhog/frontend/app/dashboard/widgets/PortfolioProjectsKpi.tsx.ejs +96 -0
- package/hedhog/frontend/app/dashboard/widgets/PortfolioRiskKpi.tsx.ejs +115 -0
- package/hedhog/frontend/app/dashboard/widgets/ProjectStatusOverview.tsx.ejs +120 -0
- package/hedhog/frontend/app/dashboard/widgets/StrategicDeadlines.tsx.ejs +146 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamApprovalQueue.tsx.ejs +108 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamCapacityKpi.tsx.ejs +97 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamHeadcountKpi.tsx.ejs +100 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamHoursKpi.tsx.ejs +104 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamPendingApprovalsKpi.tsx.ejs +110 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamUtilizationOverview.tsx.ejs +115 -0
- package/hedhog/frontend/app/dashboard/widgets/TeamWorkloadAlerts.tsx.ejs +117 -0
- package/hedhog/frontend/app/dashboard/widgets/index.ts.ejs +26 -0
- package/hedhog/frontend/app/departments/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/my-projects/page.tsx.ejs +30 -12
- package/hedhog/frontend/app/my-tasks/page.tsx.ejs +286 -125
- package/hedhog/frontend/app/project-cost-categories/page.tsx.ejs +58 -52
- package/hedhog/frontend/app/project-cost-types/page.tsx.ejs +58 -51
- package/hedhog/frontend/app/projects/page.tsx.ejs +415 -33
- package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/tasks-gantt/page.tsx.ejs +953 -0
- package/hedhog/frontend/app/time-off/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/timesheets/page.tsx.ejs +10 -4
- package/hedhog/frontend/messages/en.json +332 -46
- package/hedhog/frontend/messages/operations/en.json +61 -52
- package/hedhog/frontend/messages/operations/pt.json +59 -43
- package/hedhog/frontend/messages/pt.json +332 -46
- package/hedhog/frontend/widgets/capacity-distribution.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/effort-by-project.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/headcount-by-area.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/index.ts.ejs +25 -0
- package/hedhog/frontend/widgets/managed-projects-status.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-hours-period-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-open-requests-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-pending-requests-list.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-project-allocations-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-quick-actions.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-relevant-deadlines.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-timesheet-status-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/my-weekly-journey.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/portfolio-costs-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/portfolio-effort-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/portfolio-projects-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/portfolio-risk-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/project-status-overview.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/shared-operations-widget.tsx.ejs +170 -0
- package/hedhog/frontend/widgets/strategic-deadlines.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-approval-queue.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-capacity-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-headcount-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-hours-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-pending-approvals-kpi.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-utilization-overview.tsx.ejs +17 -0
- package/hedhog/frontend/widgets/team-workload-alerts.tsx.ejs +17 -0
- package/hedhog/table/operations_collaborator.yaml +8 -13
- package/hedhog/table/operations_collaborator_invoice.yaml +35 -0
- package/hedhog/table/operations_collaborator_payment.yaml +32 -0
- package/hedhog/table/operations_project.yaml +1 -1
- package/hedhog/table/operations_project_file.yaml +23 -0
- package/hedhog/table/operations_task.yaml +76 -69
- package/hedhog/table/operations_task_activity.yaml +51 -0
- package/package.json +6 -5
- package/src/controllers/operations-collaborators.controller.ts +117 -8
- package/src/controllers/operations-projects.controller.ts +41 -8
- package/src/controllers/operations-tasks.controller.ts +156 -166
- package/src/dashboard/README.md +214 -0
- package/src/dashboard/components/DashboardLayout.tsx +131 -0
- package/src/dashboard/components/widget-registry.ts +255 -0
- package/src/dashboard/hooks/useDashboardData.ts +29 -0
- package/src/dashboard/types/widgets.types.ts +237 -0
- package/src/dashboard/widgets/CapacityDistribution.tsx +56 -0
- package/src/dashboard/widgets/EffortByProject.tsx +51 -0
- package/src/dashboard/widgets/HeadcountByArea.tsx +57 -0
- package/src/dashboard/widgets/ManagedProjectsStatus.tsx +53 -0
- package/src/dashboard/widgets/MyHoursPeriodKpi.tsx +87 -0
- package/src/dashboard/widgets/MyOpenRequestsKpi.tsx +51 -0
- package/src/dashboard/widgets/MyPendingRequestsList.tsx +63 -0
- package/src/dashboard/widgets/MyProjectAllocationsKpi.tsx +57 -0
- package/src/dashboard/widgets/MyQuickActions.tsx +62 -0
- package/src/dashboard/widgets/MyRelevantDeadlines.tsx +84 -0
- package/src/dashboard/widgets/MyTimesheetStatusKpi.tsx +65 -0
- package/src/dashboard/widgets/MyWeeklyJourney.tsx +57 -0
- package/src/dashboard/widgets/PortfolioCostsKpi.tsx +48 -0
- package/src/dashboard/widgets/PortfolioEffortKpi.tsx +41 -0
- package/src/dashboard/widgets/PortfolioRiskKpi.tsx +50 -0
- package/src/dashboard/widgets/ProjectStatusOverview.tsx +52 -0
- package/src/dashboard/widgets/StrategicDeadlines.tsx +93 -0
- package/src/dashboard/widgets/TeamApprovalQueue.tsx +70 -0
- package/src/dashboard/widgets/TeamCapacityKpi.tsx +50 -0
- package/src/dashboard/widgets/TeamHoursKpi.tsx +51 -0
- package/src/dashboard/widgets/TeamPendingApprovalsKpi.tsx +53 -0
- package/src/dashboard/widgets/TeamUtilizationOverview.tsx +62 -0
- package/src/dashboard/widgets/TeamWorkloadAlerts.tsx +81 -0
- package/src/dashboard/widgets/index.ts +26 -0
- package/src/dto/create-collaborator-invoice.dto.ts +39 -0
- package/src/dto/create-collaborator-payment.dto.ts +35 -0
- package/src/dto/create-collaborator.dto.ts +4 -11
- package/src/dto/list-collaborator-invoice.dto.ts +3 -0
- package/src/dto/list-collaborator-payment.dto.ts +3 -0
- package/src/dto/update-collaborator-invoice.dto.ts +6 -0
- package/src/dto/update-collaborator-payment.dto.ts +6 -0
- package/src/index.ts +3 -0
- package/src/operations.service.spec.ts +988 -764
- package/src/operations.service.ts +4689 -2624
|
@@ -7,6 +7,7 @@ import { Button } from '@/components/ui/button';
|
|
|
7
7
|
import {
|
|
8
8
|
Dialog,
|
|
9
9
|
DialogContent,
|
|
10
|
+
DialogDescription,
|
|
10
11
|
DialogFooter,
|
|
11
12
|
DialogHeader,
|
|
12
13
|
DialogTitle,
|
|
@@ -39,12 +40,14 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|
|
39
40
|
import {
|
|
40
41
|
closestCenter,
|
|
41
42
|
DndContext,
|
|
43
|
+
DragOverlay,
|
|
42
44
|
PointerSensor,
|
|
43
45
|
useDraggable,
|
|
44
46
|
useDroppable,
|
|
45
47
|
useSensor,
|
|
46
48
|
useSensors,
|
|
47
49
|
type DragEndEvent,
|
|
50
|
+
type DragStartEvent,
|
|
48
51
|
type UniqueIdentifier,
|
|
49
52
|
} from '@dnd-kit/core';
|
|
50
53
|
import { CSS } from '@dnd-kit/utilities';
|
|
@@ -60,6 +63,7 @@ import {
|
|
|
60
63
|
Paperclip,
|
|
61
64
|
Pencil,
|
|
62
65
|
Plus,
|
|
66
|
+
Send,
|
|
63
67
|
Timer,
|
|
64
68
|
Trash2,
|
|
65
69
|
} from 'lucide-react';
|
|
@@ -86,6 +90,7 @@ import {
|
|
|
86
90
|
type TaskDetailSheetData,
|
|
87
91
|
} from './task-detail-sheet';
|
|
88
92
|
import { TaskFileAttachments } from './task-file-attachments';
|
|
93
|
+
import { TimesheetEntryCreateSheet } from './timesheet-entry-create-sheet';
|
|
89
94
|
|
|
90
95
|
type BoardColumnId = 'todo' | 'doing' | 'review' | 'done';
|
|
91
96
|
|
|
@@ -104,6 +109,8 @@ type BoardTask = {
|
|
|
104
109
|
assigneePersonAvatarId: number | null;
|
|
105
110
|
commentCount: number;
|
|
106
111
|
fileCount: number;
|
|
112
|
+
doingStartedAt: string | null;
|
|
113
|
+
totalDoingMinutes: number;
|
|
107
114
|
};
|
|
108
115
|
|
|
109
116
|
type TaskFormState = {
|
|
@@ -111,6 +118,7 @@ type TaskFormState = {
|
|
|
111
118
|
description: string;
|
|
112
119
|
priority: 'low' | 'medium' | 'high';
|
|
113
120
|
status: BoardColumnId;
|
|
121
|
+
assigneeCollaboratorId: string;
|
|
114
122
|
dueDate: string;
|
|
115
123
|
estimateHours: string;
|
|
116
124
|
tags: string;
|
|
@@ -121,6 +129,7 @@ const EMPTY_TASK_FORM: TaskFormState = {
|
|
|
121
129
|
description: '',
|
|
122
130
|
priority: 'medium',
|
|
123
131
|
status: 'todo',
|
|
132
|
+
assigneeCollaboratorId: 'none',
|
|
124
133
|
dueDate: '',
|
|
125
134
|
estimateHours: '',
|
|
126
135
|
tags: '',
|
|
@@ -133,6 +142,14 @@ type BoardState = {
|
|
|
133
142
|
columns: BoardColumns;
|
|
134
143
|
};
|
|
135
144
|
|
|
145
|
+
type TimesheetEntryPrefill = {
|
|
146
|
+
projectId: number;
|
|
147
|
+
projectAssignmentId?: number | null;
|
|
148
|
+
projectLabel: string;
|
|
149
|
+
taskId: number;
|
|
150
|
+
taskLabel: string;
|
|
151
|
+
};
|
|
152
|
+
|
|
136
153
|
const KANBAN_COLUMNS: Array<{ id: BoardColumnId; label: string }> = [
|
|
137
154
|
{ id: 'todo', label: 'Backlog' },
|
|
138
155
|
{ id: 'doing', label: 'Em execução' },
|
|
@@ -163,8 +180,16 @@ function parseColumnId(
|
|
|
163
180
|
return KANBAN_COLUMNS.some((c) => c.id === id) ? (id as BoardColumnId) : null;
|
|
164
181
|
}
|
|
165
182
|
|
|
183
|
+
function normalizeDateInputValue(value?: string | null) {
|
|
184
|
+
if (!value) return '';
|
|
185
|
+
const match = String(value)
|
|
186
|
+
.trim()
|
|
187
|
+
.match(/^\d{4}-\d{2}-\d{2}/);
|
|
188
|
+
return match?.[0] ?? '';
|
|
189
|
+
}
|
|
190
|
+
|
|
166
191
|
function apiTaskToBoardTask(
|
|
167
|
-
row: OperationsMyProjectSummary['tasks'][number]
|
|
192
|
+
row: OperationsMyProjectSummary['tasks'][number] | OperationsTaskOption
|
|
168
193
|
): BoardTask {
|
|
169
194
|
const status = KANBAN_COLUMNS.some((c) => c.id === row.status)
|
|
170
195
|
? (row.status as BoardColumnId)
|
|
@@ -172,6 +197,8 @@ function apiTaskToBoardTask(
|
|
|
172
197
|
const taskCounts = row as typeof row & {
|
|
173
198
|
commentCount?: number | null;
|
|
174
199
|
fileCount?: number | null;
|
|
200
|
+
doingStartedAt?: string | null;
|
|
201
|
+
totalDoingMinutes?: number | null;
|
|
175
202
|
};
|
|
176
203
|
|
|
177
204
|
return {
|
|
@@ -191,6 +218,8 @@ function apiTaskToBoardTask(
|
|
|
191
218
|
((row as unknown as Record<string, unknown>).commentCount as number) ?? 0,
|
|
192
219
|
fileCount:
|
|
193
220
|
((row as unknown as Record<string, unknown>).fileCount as number) ?? 0,
|
|
221
|
+
doingStartedAt: taskCounts.doingStartedAt ?? null,
|
|
222
|
+
totalDoingMinutes: taskCounts.totalDoingMinutes ?? 0,
|
|
194
223
|
};
|
|
195
224
|
}
|
|
196
225
|
|
|
@@ -203,6 +232,23 @@ function splitTasksByColumn(tasks: BoardTask[]): BoardColumns {
|
|
|
203
232
|
};
|
|
204
233
|
}
|
|
205
234
|
|
|
235
|
+
function replaceTaskInColumns(
|
|
236
|
+
columns: BoardColumns,
|
|
237
|
+
task: BoardTask
|
|
238
|
+
): BoardColumns {
|
|
239
|
+
const nextColumns = {
|
|
240
|
+
todo: columns.todo.filter((item) => item.id !== task.id),
|
|
241
|
+
doing: columns.doing.filter((item) => item.id !== task.id),
|
|
242
|
+
review: columns.review.filter((item) => item.id !== task.id),
|
|
243
|
+
done: columns.done.filter((item) => item.id !== task.id),
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
return {
|
|
247
|
+
...nextColumns,
|
|
248
|
+
[task.status]: [task, ...nextColumns[task.status]],
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
206
252
|
function getInitials(value?: string | null) {
|
|
207
253
|
const parts = String(value ?? '')
|
|
208
254
|
.trim()
|
|
@@ -225,26 +271,6 @@ function getUserPhotoUrl(photoId?: number | null) {
|
|
|
225
271
|
: null;
|
|
226
272
|
}
|
|
227
273
|
|
|
228
|
-
function normalizeDateInputValue(value?: string | null) {
|
|
229
|
-
if (!value) {
|
|
230
|
-
return '';
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
const normalizedValue = String(value).trim();
|
|
234
|
-
const directMatch = normalizedValue.match(/^\d{4}-\d{2}-\d{2}/);
|
|
235
|
-
|
|
236
|
-
if (directMatch?.[0]) {
|
|
237
|
-
return directMatch[0];
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
const parsedDate = new Date(normalizedValue);
|
|
241
|
-
if (Number.isNaN(parsedDate.getTime())) {
|
|
242
|
-
return '';
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
return parsedDate.toISOString().slice(0, 10);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
274
|
function getTaskPriorityLabel(value?: string | null) {
|
|
249
275
|
const labels: Record<string, string> = {
|
|
250
276
|
low: 'Baixa',
|
|
@@ -326,10 +352,12 @@ function DraggableTaskCard({
|
|
|
326
352
|
return (
|
|
327
353
|
<div
|
|
328
354
|
ref={setNodeRef}
|
|
329
|
-
style={{
|
|
355
|
+
style={{
|
|
356
|
+
transform: CSS.Translate.toString(transform),
|
|
357
|
+
...(isDragging ? { opacity: 0, pointerEvents: 'none' } : {}),
|
|
358
|
+
}}
|
|
330
359
|
{...listeners}
|
|
331
360
|
{...attributes}
|
|
332
|
-
className={isDragging ? 'z-20' : undefined}
|
|
333
361
|
>
|
|
334
362
|
{children(isDragging)}
|
|
335
363
|
</div>
|
|
@@ -352,7 +380,6 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
352
380
|
const commonT = useTranslations('operations.Common');
|
|
353
381
|
const formT = useTranslations('operations.ProjectFormPage');
|
|
354
382
|
const { request, currentLocaleCode, getSettingValue } = useApp();
|
|
355
|
-
|
|
356
383
|
const mentionItems = useMentionItems(request);
|
|
357
384
|
|
|
358
385
|
const getProjectStatusLabel = (value?: string | null) => {
|
|
@@ -397,7 +424,12 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
397
424
|
const [editingTaskId, setEditingTaskId] = useState<number | null>(null);
|
|
398
425
|
const [taskFormData, setTaskFormData] =
|
|
399
426
|
useState<TaskFormState>(EMPTY_TASK_FORM);
|
|
427
|
+
const [activeDragTask, setActiveDragTask] = useState<BoardTask | null>(null);
|
|
400
428
|
const [taskFormLoading, setTaskFormLoading] = useState(false);
|
|
429
|
+
const [isTimesheetEntrySheetOpen, setIsTimesheetEntrySheetOpen] =
|
|
430
|
+
useState(false);
|
|
431
|
+
const [timesheetPrefill, setTimesheetPrefill] =
|
|
432
|
+
useState<TimesheetEntryPrefill | null>(null);
|
|
401
433
|
|
|
402
434
|
const apiTasks = useMemo(
|
|
403
435
|
() => (project?.tasks ?? []).map(apiTaskToBoardTask),
|
|
@@ -429,6 +461,27 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
429
461
|
return splitTasksByColumn(apiTasks);
|
|
430
462
|
}, [project, boardState, apiTasks]);
|
|
431
463
|
|
|
464
|
+
const taskAssigneeOptions = useMemo(() => {
|
|
465
|
+
const seen = new Set<number>();
|
|
466
|
+
return (
|
|
467
|
+
project?.assignments
|
|
468
|
+
.filter((assignment) => {
|
|
469
|
+
if (
|
|
470
|
+
!assignment.collaboratorId ||
|
|
471
|
+
seen.has(assignment.collaboratorId)
|
|
472
|
+
) {
|
|
473
|
+
return false;
|
|
474
|
+
}
|
|
475
|
+
seen.add(assignment.collaboratorId);
|
|
476
|
+
return true;
|
|
477
|
+
})
|
|
478
|
+
.map((assignment) => ({
|
|
479
|
+
id: String(assignment.collaboratorId),
|
|
480
|
+
label: assignment.collaboratorName,
|
|
481
|
+
})) ?? []
|
|
482
|
+
);
|
|
483
|
+
}, [project]);
|
|
484
|
+
|
|
432
485
|
const sensors = useSensors(
|
|
433
486
|
useSensor(PointerSensor, { activationConstraint: { distance: 6 } })
|
|
434
487
|
);
|
|
@@ -464,31 +517,73 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
464
517
|
},
|
|
465
518
|
});
|
|
466
519
|
|
|
467
|
-
mutateOperations(
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
520
|
+
mutateOperations<OperationsTaskOption>(
|
|
521
|
+
request,
|
|
522
|
+
`/operations/tasks/${taskId}`,
|
|
523
|
+
'PATCH',
|
|
524
|
+
{
|
|
525
|
+
status: targetColumn,
|
|
526
|
+
}
|
|
527
|
+
)
|
|
528
|
+
.then((updatedTask) => {
|
|
529
|
+
if (!updatedTask) {
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
const updatedBoardTask = apiTaskToBoardTask(updatedTask);
|
|
534
|
+
setBoardState((current) => ({
|
|
535
|
+
projectId: current?.projectId ?? project.id,
|
|
536
|
+
columns: replaceTaskInColumns(
|
|
537
|
+
current?.columns ?? taskColumns,
|
|
538
|
+
updatedBoardTask
|
|
539
|
+
),
|
|
540
|
+
}));
|
|
541
|
+
})
|
|
542
|
+
.catch(() => {
|
|
543
|
+
setBoardState(null);
|
|
544
|
+
void refetch();
|
|
545
|
+
});
|
|
473
546
|
},
|
|
474
547
|
[taskColumns, project, request, refetch] // eslint-disable-line react-hooks/exhaustive-deps
|
|
475
548
|
);
|
|
476
549
|
|
|
477
550
|
const onBoardDragEnd = (event: DragEndEvent) => {
|
|
551
|
+
setActiveDragTask(null);
|
|
478
552
|
const taskId = parseTaskId(event.active.id);
|
|
479
553
|
const targetColumn = parseColumnId(event.over?.id);
|
|
480
554
|
if (!taskId || !targetColumn) return;
|
|
481
555
|
moveTaskToColumn(taskId, targetColumn);
|
|
482
556
|
};
|
|
483
557
|
|
|
558
|
+
const onBoardDragStart = (event: DragStartEvent) => {
|
|
559
|
+
const taskId = parseTaskId(event.active.id);
|
|
560
|
+
if (!taskId) {
|
|
561
|
+
setActiveDragTask(null);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const task = KANBAN_COLUMNS.map((column) => taskColumns[column.id])
|
|
566
|
+
.find((items) => items.some((item) => item.id === taskId))
|
|
567
|
+
?.find((item) => item.id === taskId);
|
|
568
|
+
|
|
569
|
+
setActiveDragTask(task ?? null);
|
|
570
|
+
};
|
|
571
|
+
|
|
484
572
|
const openCreateTaskForm = useCallback(
|
|
485
573
|
(defaultStatus: BoardColumnId = 'todo') => {
|
|
486
574
|
setEditingTaskId(null);
|
|
487
|
-
setTaskFormData({
|
|
575
|
+
setTaskFormData({
|
|
576
|
+
...EMPTY_TASK_FORM,
|
|
577
|
+
status: defaultStatus,
|
|
578
|
+
assigneeCollaboratorId:
|
|
579
|
+
currentCollaboratorId != null
|
|
580
|
+
? String(currentCollaboratorId)
|
|
581
|
+
: 'none',
|
|
582
|
+
});
|
|
488
583
|
setSelectedTask(null);
|
|
489
584
|
setTaskFormOpen(true);
|
|
490
585
|
},
|
|
491
|
-
[]
|
|
586
|
+
[currentCollaboratorId]
|
|
492
587
|
);
|
|
493
588
|
|
|
494
589
|
const openEditTaskForm = useCallback((task: BoardTask) => {
|
|
@@ -498,6 +593,9 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
498
593
|
description: task.description ?? '',
|
|
499
594
|
priority: task.priority as TaskFormState['priority'],
|
|
500
595
|
status: task.status,
|
|
596
|
+
assigneeCollaboratorId: task.assigneeCollaboratorId
|
|
597
|
+
? String(task.assigneeCollaboratorId)
|
|
598
|
+
: 'none',
|
|
501
599
|
dueDate: normalizeDateInputValue(task.dueDate),
|
|
502
600
|
estimateHours:
|
|
503
601
|
task.estimateHours != null ? String(task.estimateHours) : '',
|
|
@@ -519,7 +617,10 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
519
617
|
const payload: Record<string, unknown> = {
|
|
520
618
|
projectId,
|
|
521
619
|
projectAssignmentId: project?.myAssignmentId ?? null,
|
|
522
|
-
assigneeCollaboratorId:
|
|
620
|
+
assigneeCollaboratorId:
|
|
621
|
+
taskFormData.assigneeCollaboratorId !== 'none'
|
|
622
|
+
? Number(taskFormData.assigneeCollaboratorId)
|
|
623
|
+
: null,
|
|
523
624
|
name: taskFormData.name.trim(),
|
|
524
625
|
description: taskFormData.description || null,
|
|
525
626
|
priority: taskFormData.priority,
|
|
@@ -550,15 +651,7 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
550
651
|
} finally {
|
|
551
652
|
setTaskFormLoading(false);
|
|
552
653
|
}
|
|
553
|
-
}, [
|
|
554
|
-
currentCollaboratorId,
|
|
555
|
-
editingTaskId,
|
|
556
|
-
project,
|
|
557
|
-
projectId,
|
|
558
|
-
refetchAll,
|
|
559
|
-
request,
|
|
560
|
-
taskFormData,
|
|
561
|
-
]);
|
|
654
|
+
}, [editingTaskId, project, projectId, refetchAll, request, taskFormData]);
|
|
562
655
|
|
|
563
656
|
const [archivingTaskId, setArchivingTaskId] = useState<number | null>(null);
|
|
564
657
|
|
|
@@ -612,6 +705,29 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
612
705
|
[request, refetchAll]
|
|
613
706
|
);
|
|
614
707
|
|
|
708
|
+
const openTimesheetEntrySheet = useCallback(
|
|
709
|
+
(task: TaskDetailSheetData) => {
|
|
710
|
+
if (!project) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
const projectLabel = [project.name, project.code]
|
|
715
|
+
.filter(Boolean)
|
|
716
|
+
.join(' • ');
|
|
717
|
+
|
|
718
|
+
setTimesheetPrefill({
|
|
719
|
+
projectId,
|
|
720
|
+
projectAssignmentId: project.myAssignmentId ?? null,
|
|
721
|
+
projectLabel: projectLabel || commonT('labels.notAssigned'),
|
|
722
|
+
taskId: task.id,
|
|
723
|
+
taskLabel: task.name,
|
|
724
|
+
});
|
|
725
|
+
setSelectedTask(null);
|
|
726
|
+
setIsTimesheetEntrySheetOpen(true);
|
|
727
|
+
},
|
|
728
|
+
[commonT, project, projectId]
|
|
729
|
+
);
|
|
730
|
+
|
|
615
731
|
if (!project) {
|
|
616
732
|
return (
|
|
617
733
|
<Page>
|
|
@@ -708,6 +824,8 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
708
824
|
<DndContext
|
|
709
825
|
sensors={sensors}
|
|
710
826
|
collisionDetection={closestCenter}
|
|
827
|
+
onDragStart={onBoardDragStart}
|
|
828
|
+
onDragCancel={() => setActiveDragTask(null)}
|
|
711
829
|
onDragEnd={onBoardDragEnd}
|
|
712
830
|
>
|
|
713
831
|
<div className="grid gap-4 xl:grid-cols-4">
|
|
@@ -716,7 +834,7 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
716
834
|
{(isOver) => (
|
|
717
835
|
<div
|
|
718
836
|
className={[
|
|
719
|
-
'flex min-h-
|
|
837
|
+
'flex min-h-48 max-h-160 flex-col rounded-3xl border bg-linear-to-b p-3 transition-all',
|
|
720
838
|
getColumnClassName(column.id),
|
|
721
839
|
isOver
|
|
722
840
|
? 'border-primary shadow-lg ring-2 ring-primary/15'
|
|
@@ -752,7 +870,7 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
752
870
|
</div>
|
|
753
871
|
</div>
|
|
754
872
|
|
|
755
|
-
<div className="flex flex-1 flex-col gap-2">
|
|
873
|
+
<div className="flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto pb-1 pr-0.5">
|
|
756
874
|
<AnimatePresence initial={false}>
|
|
757
875
|
{taskColumns[column.id].map((task) => {
|
|
758
876
|
const tags = getTaskTags(task);
|
|
@@ -924,6 +1042,18 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
924
1042
|
</DroppableColumn>
|
|
925
1043
|
))}
|
|
926
1044
|
</div>
|
|
1045
|
+
<DragOverlay zIndex={1200}>
|
|
1046
|
+
{activeDragTask ? (
|
|
1047
|
+
<div className="w-76 cursor-grabbing rounded-2xl border border-primary/60 bg-card p-3 text-left shadow-2xl ring-2 ring-primary/20 opacity-95">
|
|
1048
|
+
<p className="line-clamp-2 text-sm font-semibold leading-snug">
|
|
1049
|
+
{activeDragTask.name}
|
|
1050
|
+
</p>
|
|
1051
|
+
<p className="mt-1 truncate text-xs text-muted-foreground">
|
|
1052
|
+
{activeDragTask.assigneeName || commonT('labels.notAssigned')}
|
|
1053
|
+
</p>
|
|
1054
|
+
</div>
|
|
1055
|
+
) : null}
|
|
1056
|
+
</DragOverlay>
|
|
927
1057
|
</DndContext>
|
|
928
1058
|
</SectionCard>
|
|
929
1059
|
|
|
@@ -1091,13 +1221,13 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
1091
1221
|
}}
|
|
1092
1222
|
footer={
|
|
1093
1223
|
selectedTask ? (
|
|
1094
|
-
<div className="grid grid-cols-
|
|
1224
|
+
<div className="grid grid-cols-1 gap-3 sm:grid-cols-3">
|
|
1095
1225
|
{archivedTasks.some((task) => task.id === selectedTask.id) ? (
|
|
1096
1226
|
<>
|
|
1097
1227
|
<Button
|
|
1098
1228
|
variant="outline"
|
|
1099
1229
|
size="sm"
|
|
1100
|
-
className="h-10 gap-2"
|
|
1230
|
+
className="h-10 gap-2 sm:col-span-2"
|
|
1101
1231
|
onClick={() => void handleRestoreTask(selectedTask.id)}
|
|
1102
1232
|
>
|
|
1103
1233
|
<ArchiveRestore className="size-3.5" />
|
|
@@ -1115,6 +1245,15 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
1115
1245
|
</>
|
|
1116
1246
|
) : (
|
|
1117
1247
|
<>
|
|
1248
|
+
<Button
|
|
1249
|
+
variant="outline"
|
|
1250
|
+
size="sm"
|
|
1251
|
+
className="h-10 gap-2"
|
|
1252
|
+
onClick={() => openTimesheetEntrySheet(selectedTask)}
|
|
1253
|
+
>
|
|
1254
|
+
<Send className="size-3.5" />
|
|
1255
|
+
{commonT('actions.logHours')}
|
|
1256
|
+
</Button>
|
|
1118
1257
|
<Button
|
|
1119
1258
|
variant="outline"
|
|
1120
1259
|
size="sm"
|
|
@@ -1140,13 +1279,42 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
1140
1279
|
}
|
|
1141
1280
|
/>
|
|
1142
1281
|
|
|
1282
|
+
<TimesheetEntryCreateSheet
|
|
1283
|
+
open={isTimesheetEntrySheetOpen}
|
|
1284
|
+
onOpenChange={(open) => {
|
|
1285
|
+
setIsTimesheetEntrySheetOpen(open);
|
|
1286
|
+
if (!open) {
|
|
1287
|
+
setTimesheetPrefill(null);
|
|
1288
|
+
}
|
|
1289
|
+
}}
|
|
1290
|
+
project={
|
|
1291
|
+
timesheetPrefill
|
|
1292
|
+
? {
|
|
1293
|
+
id: timesheetPrefill.projectId,
|
|
1294
|
+
label: timesheetPrefill.projectLabel,
|
|
1295
|
+
projectAssignmentId: timesheetPrefill.projectAssignmentId,
|
|
1296
|
+
}
|
|
1297
|
+
: null
|
|
1298
|
+
}
|
|
1299
|
+
task={
|
|
1300
|
+
timesheetPrefill
|
|
1301
|
+
? {
|
|
1302
|
+
id: timesheetPrefill.taskId,
|
|
1303
|
+
label: timesheetPrefill.taskLabel,
|
|
1304
|
+
}
|
|
1305
|
+
: null
|
|
1306
|
+
}
|
|
1307
|
+
onCreated={() => {
|
|
1308
|
+
void refetchAll();
|
|
1309
|
+
}}
|
|
1310
|
+
/>
|
|
1311
|
+
|
|
1143
1312
|
<Sheet
|
|
1144
1313
|
open={taskFormOpen}
|
|
1145
1314
|
onOpenChange={(open) => {
|
|
1146
1315
|
if (!open) {
|
|
1147
1316
|
setTaskFormOpen(false);
|
|
1148
1317
|
setEditingTaskId(null);
|
|
1149
|
-
setTaskFormData(EMPTY_TASK_FORM);
|
|
1150
1318
|
}
|
|
1151
1319
|
}}
|
|
1152
1320
|
>
|
|
@@ -1257,6 +1425,35 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
1257
1425
|
</div>
|
|
1258
1426
|
</div>
|
|
1259
1427
|
|
|
1428
|
+
<div className="space-y-1.5">
|
|
1429
|
+
<Label>{commonT('responsible')}</Label>
|
|
1430
|
+
<Select
|
|
1431
|
+
value={taskFormData.assigneeCollaboratorId}
|
|
1432
|
+
onValueChange={(value) =>
|
|
1433
|
+
setTaskFormData((prev) => ({
|
|
1434
|
+
...prev,
|
|
1435
|
+
assigneeCollaboratorId: value,
|
|
1436
|
+
}))
|
|
1437
|
+
}
|
|
1438
|
+
>
|
|
1439
|
+
<SelectTrigger className="w-full">
|
|
1440
|
+
<SelectValue
|
|
1441
|
+
placeholder={commonT('labels.notAssigned')}
|
|
1442
|
+
/>
|
|
1443
|
+
</SelectTrigger>
|
|
1444
|
+
<SelectContent>
|
|
1445
|
+
<SelectItem value="none">
|
|
1446
|
+
{commonT('labels.notAssigned')}
|
|
1447
|
+
</SelectItem>
|
|
1448
|
+
{taskAssigneeOptions.map((option) => (
|
|
1449
|
+
<SelectItem key={option.id} value={option.id}>
|
|
1450
|
+
{option.label}
|
|
1451
|
+
</SelectItem>
|
|
1452
|
+
))}
|
|
1453
|
+
</SelectContent>
|
|
1454
|
+
</Select>
|
|
1455
|
+
</div>
|
|
1456
|
+
|
|
1260
1457
|
<div className="grid grid-cols-2 gap-3">
|
|
1261
1458
|
<div className="space-y-1.5">
|
|
1262
1459
|
<Label htmlFor="task-due-date">
|
|
@@ -1398,10 +1595,10 @@ export function MyProjectSummaryScreen({ projectId }: { projectId: number }) {
|
|
|
1398
1595
|
<DialogContent className="sm:max-w-lg">
|
|
1399
1596
|
<DialogHeader>
|
|
1400
1597
|
<DialogTitle>{t('dialogs.deleteTitle')}</DialogTitle>
|
|
1598
|
+
<DialogDescription>
|
|
1599
|
+
{t('dialogs.deleteDescription')}
|
|
1600
|
+
</DialogDescription>
|
|
1401
1601
|
</DialogHeader>
|
|
1402
|
-
<p className="text-sm text-muted-foreground">
|
|
1403
|
-
{t('dialogs.deleteDescription')}
|
|
1404
|
-
</p>
|
|
1405
1602
|
<DialogFooter className="gap-2 sm:justify-between">
|
|
1406
1603
|
<Button variant="ghost" onClick={() => setDeletePromptTask(null)}>
|
|
1407
1604
|
{commonT('actions.cancel')}
|