@hed-hog/operations 0.0.329 → 0.0.331
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 +7 -216
- package/dist/controllers/operations-collaborators.controller.d.ts.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 +30 -5
- 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.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/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 +178 -264
- package/dist/operations.service.d.ts.map +1 -1
- package/dist/operations.service.js +2170 -1340
- 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_component_role.yaml +8 -8
- package/hedhog/data/dashboard_item.yaml +25 -25
- package/hedhog/data/dashboard_role.yaml +1 -1
- package/hedhog/data/menu.yaml +6 -16
- package/hedhog/data/role.yaml +1 -1
- package/hedhog/data/route.yaml +116 -55
- package/hedhog/frontend/app/_components/async-options-combobox.tsx.ejs +15 -9
- package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +39 -99
- package/hedhog/frontend/app/_components/collaborator-picker.tsx.ejs +158 -0
- package/hedhog/frontend/app/_components/my-project-summary-screen.tsx.ejs +314 -116
- package/hedhog/frontend/app/_components/project-assignments-tab.tsx.ejs +434 -449
- package/hedhog/frontend/app/_components/project-costs-section.tsx.ejs +51 -81
- package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +328 -423
- package/hedhog/frontend/app/_components/project-file-attachments.tsx.ejs +371 -0
- package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +446 -377
- package/hedhog/frontend/app/_components/task-detail-sheet.tsx.ejs +803 -581
- package/hedhog/frontend/app/_components/task-file-attachments.tsx.ejs +14 -9
- 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 +480 -476
- package/hedhog/frontend/app/_lib/hooks/use-values-visibility.ts.ejs +61 -0
- package/hedhog/frontend/app/_lib/types.ts.ejs +66 -5
- package/hedhog/frontend/app/_lib/utils/format.ts.ejs +0 -2
- package/hedhog/frontend/app/_lib/utils/task-ui.ts.ejs +43 -0
- package/hedhog/frontend/app/approvals/page.tsx.ejs +11 -2
- package/hedhog/frontend/app/collaborator-types/page.tsx.ejs +6 -1
- package/hedhog/frontend/app/collaborators/page.tsx.ejs +127 -42
- 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 +59 -16
- package/hedhog/frontend/app/my-tasks/page.tsx.ejs +329 -106
- 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 +436 -35
- package/hedhog/frontend/app/reports/collaborators/page.tsx.ejs +65 -52
- package/hedhog/frontend/app/reports/projects/page.tsx.ejs +80 -82
- package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +13 -2
- 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 +460 -61
- package/hedhog/frontend/messages/operations/en.json +61 -52
- package/hedhog/frontend/messages/operations/pt.json +59 -43
- package/hedhog/frontend/messages/pt.json +460 -61
- 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_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 +7 -6
- 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.dto.ts +4 -11
- package/src/index.ts +3 -0
- package/src/operations.service.spec.ts +988 -764
- package/src/operations.service.ts +4300 -2538
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Dashboard Widgets - Operations Module
|
|
2
|
+
|
|
3
|
+
## Arquitetura
|
|
4
|
+
|
|
5
|
+
O dashboard do módulo operations segue um padrão de composição modular com 3 camadas de widgets baseados em roles:
|
|
6
|
+
|
|
7
|
+
### Roles e Widgets
|
|
8
|
+
|
|
9
|
+
| Role | Widgets | Descrição |
|
|
10
|
+
|------|---------|-----------|
|
|
11
|
+
| `operations-collaborator` | 8 widgets | Visão pessoal: horas, timesheet, alocações, solicitações, prazos, ações rápidas |
|
|
12
|
+
| `admin-operations-supervisor` | 8 widgets | Visão de time: headcount, aprovações, horas, capacidade, utilização, alertas, projetos, fila |
|
|
13
|
+
| `admin-operations-director` | 7 widgets | Visão de portfólio: projetos, custos, esforço, risco, status, distribuição, prazos |
|
|
14
|
+
|
|
15
|
+
### Estrutura de Pastas
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
src/dashboard/
|
|
19
|
+
├── hooks/
|
|
20
|
+
│ └── useDashboardData.ts # Hook para buscar dados do backend
|
|
21
|
+
├── types/
|
|
22
|
+
│ └── widgets.types.ts # Tipos TypeScript para dados de widgets
|
|
23
|
+
├── components/
|
|
24
|
+
│ └── DashboardLayout.tsx # Layout principal que renderiza widgets
|
|
25
|
+
└── widgets/
|
|
26
|
+
├── MyHoursPeriodKpi.tsx # Exemplo: Collaborator widget
|
|
27
|
+
├── TeamHeadcountKpi.tsx # Exemplo: Supervisor widget
|
|
28
|
+
├── PortfolioProjectsKpi.tsx # Exemplo: Director widget
|
|
29
|
+
└── [outros widgets...] # A implementar
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Como Adicionar um Novo Widget
|
|
33
|
+
|
|
34
|
+
### 1. Defina o tipo de dados em `types/widgets.types.ts`
|
|
35
|
+
|
|
36
|
+
Adicione a interface de dados para seu widget:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
export interface MyNewWidgetData {
|
|
40
|
+
title: string;
|
|
41
|
+
value: number;
|
|
42
|
+
// ... outros campos
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Crie o componente widget
|
|
47
|
+
|
|
48
|
+
Crie um arquivo em `widgets/MyNewWidget.tsx`:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
'use client';
|
|
52
|
+
|
|
53
|
+
import React from 'react';
|
|
54
|
+
|
|
55
|
+
interface MyNewWidgetProps {
|
|
56
|
+
slug: string;
|
|
57
|
+
title: string;
|
|
58
|
+
roleSlug: string;
|
|
59
|
+
width?: number;
|
|
60
|
+
height?: number;
|
|
61
|
+
data?: MyNewWidgetData;
|
|
62
|
+
style?: React.CSSProperties;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const MyNewWidget: React.FC<MyNewWidgetProps> = ({
|
|
66
|
+
title,
|
|
67
|
+
data,
|
|
68
|
+
style,
|
|
69
|
+
}) => {
|
|
70
|
+
return (
|
|
71
|
+
<div className="bg-white rounded-lg shadow-sm p-4" style={style}>
|
|
72
|
+
<h3 className="text-sm font-medium">{title}</h3>
|
|
73
|
+
{/* Renderizar dados aqui */}
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export default MyNewWidget;
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### 3. Registre o widget em `DashboardLayout.tsx`
|
|
82
|
+
|
|
83
|
+
Adicione ao `WIDGET_REGISTRY`:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
'my-new-widget': React.lazy(() => import('./widgets/MyNewWidget')),
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 4. Configure permissões no YAML
|
|
90
|
+
|
|
91
|
+
Atualize `libraries/operations/hedhog/data/dashboard_component.yaml`:
|
|
92
|
+
|
|
93
|
+
```yaml
|
|
94
|
+
- slug: my-new-widget
|
|
95
|
+
library_slug: operations
|
|
96
|
+
width: 3
|
|
97
|
+
height: 1
|
|
98
|
+
name:
|
|
99
|
+
en: My New Widget
|
|
100
|
+
pt: Meu Novo Widget
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Atualize `libraries/operations/hedhog/data/dashboard_component_role.yaml`:
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
- component_id:
|
|
107
|
+
where:
|
|
108
|
+
slug: my-new-widget
|
|
109
|
+
role_id:
|
|
110
|
+
where:
|
|
111
|
+
slug: operations-collaborator # ou a role apropriada
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Backend Integration
|
|
115
|
+
|
|
116
|
+
### Endpoint: GET /operations/dashboard
|
|
117
|
+
|
|
118
|
+
O backend retorna dados estruturados conforme a role do usuário:
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
{
|
|
122
|
+
actor: {
|
|
123
|
+
roleScope: 'full' | 'team' | 'self',
|
|
124
|
+
collaboratorId: number,
|
|
125
|
+
collaboratorName: string,
|
|
126
|
+
teamSize: number,
|
|
127
|
+
},
|
|
128
|
+
cards: {
|
|
129
|
+
// ... dados agregados
|
|
130
|
+
},
|
|
131
|
+
recentTimesheets: [],
|
|
132
|
+
// ... dados específicos por role
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Segurança
|
|
137
|
+
|
|
138
|
+
⚠️ **IMPORTANTE:** O backend sanitiza automaticamente dados sensíveis por role:
|
|
139
|
+
|
|
140
|
+
- **Directors**: Veem TODOS os dados (salários, custos, etc.)
|
|
141
|
+
- **Supervisors**: Veem dados monetários da equipe apenas
|
|
142
|
+
- **Collaborators**: Veem APENAS seus próprios dados, não de colegas
|
|
143
|
+
|
|
144
|
+
Nenhuma sanitização adicional é necessária no frontend - confia no backend!
|
|
145
|
+
|
|
146
|
+
## Padrões de Componente
|
|
147
|
+
|
|
148
|
+
### KPI Card (Métrica simples)
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
{
|
|
152
|
+
"métrica_principal": número grande em destaque,
|
|
153
|
+
"contexto": "de total",
|
|
154
|
+
"breakdown": [array de sub-métricas],
|
|
155
|
+
"status_indicator": visual de saúde (verde/amarelo/vermelho)
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Chart/Graph (Visualização complexa)
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
{
|
|
163
|
+
"título": string,
|
|
164
|
+
"dados": array de pontos com x,y,label,
|
|
165
|
+
"legenda": tipos de dados mostrados
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Lista (Array de items)
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
{
|
|
173
|
+
"cabeçalhos": ["coluna1", "coluna2", ...],
|
|
174
|
+
"linhas": [{ coluna1: valor, coluna2: valor }, ...],
|
|
175
|
+
"paginação": opcional
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Testes
|
|
180
|
+
|
|
181
|
+
Para testar um widget com dados mock:
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
const mockData = {
|
|
185
|
+
plannedHours: 40,
|
|
186
|
+
approvedHours: 32,
|
|
187
|
+
pendingHours: 4,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
<MyHoursPeriodKpi
|
|
191
|
+
slug="my-hours-period-kpi"
|
|
192
|
+
title="Horas no Período"
|
|
193
|
+
roleSlug="operations-collaborator"
|
|
194
|
+
data={mockData}
|
|
195
|
+
/>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Loading States
|
|
199
|
+
|
|
200
|
+
Cada widget implementa um fallback de loading usando `React.Suspense`:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
<React.Suspense fallback={<SkeletonLoader />}>
|
|
204
|
+
<MyWidget data={data} />
|
|
205
|
+
</React.Suspense>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Próximas Etapas
|
|
209
|
+
|
|
210
|
+
- [ ] Implementar hook `useDashboardData` com react-query
|
|
211
|
+
- [ ] Criar 20 widgets restantes (20/23 ainda faltam)
|
|
212
|
+
- [ ] Integrar com Recharts/Chart.js para gráficos
|
|
213
|
+
- [ ] Adicionar testes unitários para cada widget
|
|
214
|
+
- [ ] Documentar parâmetros de cada widget
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Dashboard Principal - Renderiza widgets conforme role do usuário
|
|
5
|
+
*
|
|
6
|
+
* Fluxo:
|
|
7
|
+
* 1. Detecta role do usuário (collaborator/supervisor/director)
|
|
8
|
+
* 2. Busca dados via GET /operations/dashboard
|
|
9
|
+
* 3. Renderiza widgets apropriados para a role
|
|
10
|
+
* 4. Cada widget é um componente reutilizável
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import React, { useMemo } from 'react';
|
|
14
|
+
|
|
15
|
+
// Tipos de widgets por role
|
|
16
|
+
interface WidgetDefinition {
|
|
17
|
+
slug: string;
|
|
18
|
+
title: string;
|
|
19
|
+
roleSlug: string;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
xAxis: number;
|
|
23
|
+
yAxis: number;
|
|
24
|
+
componentPath: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Mapear slugs aos componentes - importados dinamicamente do admin app
|
|
28
|
+
// Os widgets estão em: apps/admin/src/app/(app)/(libraries)/operations/dashboard/widgets/
|
|
29
|
+
const WIDGET_REGISTRY: Record<string, React.ComponentType<any>> = {};
|
|
30
|
+
|
|
31
|
+
// Lazy loading de widgets - para evitar imports circulares
|
|
32
|
+
const getWidget = (slug: string): React.ComponentType<any> | null => {
|
|
33
|
+
// Este mapa será populado em runtime via importação dinâmica
|
|
34
|
+
// Por enquanto, retorna null se widget não estiver pronto
|
|
35
|
+
return WIDGET_REGISTRY[slug] || null;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
interface DashboardLayoutProps {
|
|
39
|
+
roleSlugs: string[];
|
|
40
|
+
dashboardSlug: string;
|
|
41
|
+
widgets: WidgetDefinition[];
|
|
42
|
+
data: any;
|
|
43
|
+
isLoading?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const DashboardLayout: React.FC<DashboardLayoutProps> = ({
|
|
47
|
+
roleSlugs,
|
|
48
|
+
dashboardSlug,
|
|
49
|
+
widgets,
|
|
50
|
+
data,
|
|
51
|
+
isLoading = false,
|
|
52
|
+
}) => {
|
|
53
|
+
// Filtrar widgets para a role atual
|
|
54
|
+
const visibleWidgets = useMemo(() => {
|
|
55
|
+
return widgets.filter(widget =>
|
|
56
|
+
roleSlugs.includes(widget.roleSlug)
|
|
57
|
+
);
|
|
58
|
+
}, [widgets, roleSlugs]);
|
|
59
|
+
|
|
60
|
+
if (isLoading) {
|
|
61
|
+
return (
|
|
62
|
+
<div className="grid gap-4 w-full h-full">
|
|
63
|
+
{Array(4).fill(0).map((_, i) => (
|
|
64
|
+
<div
|
|
65
|
+
key={i}
|
|
66
|
+
className="bg-gray-200 rounded-lg animate-pulse"
|
|
67
|
+
style={{ minHeight: '200px' }}
|
|
68
|
+
/>
|
|
69
|
+
))}
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<div className="grid gap-4 w-full auto-rows-max"
|
|
76
|
+
style={{
|
|
77
|
+
gridTemplateColumns: 'repeat(12, 1fr)',
|
|
78
|
+
}}>
|
|
79
|
+
{visibleWidgets.map(widget => {
|
|
80
|
+
const Component = WIDGET_REGISTRY[widget.slug];
|
|
81
|
+
|
|
82
|
+
if (!Component) {
|
|
83
|
+
return (
|
|
84
|
+
<div
|
|
85
|
+
key={widget.slug}
|
|
86
|
+
style={{
|
|
87
|
+
gridColumn: `span ${Math.min(widget.width, 12)}`,
|
|
88
|
+
gridRow: `auto / span ${widget.height}`,
|
|
89
|
+
}}
|
|
90
|
+
className="bg-red-50 border-2 border-red-200 rounded-lg p-4"
|
|
91
|
+
>
|
|
92
|
+
<p className="text-red-700 text-sm">
|
|
93
|
+
Component not found: {widget.slug}
|
|
94
|
+
</p>
|
|
95
|
+
</div>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<React.Suspense
|
|
101
|
+
key={widget.slug}
|
|
102
|
+
fallback={
|
|
103
|
+
<div
|
|
104
|
+
style={{
|
|
105
|
+
gridColumn: `span ${Math.min(widget.width, 12)}`,
|
|
106
|
+
gridRow: `auto / span ${widget.height}`,
|
|
107
|
+
}}
|
|
108
|
+
className="bg-gray-200 rounded-lg animate-pulse"
|
|
109
|
+
/>
|
|
110
|
+
}
|
|
111
|
+
>
|
|
112
|
+
<Component
|
|
113
|
+
slug={widget.slug}
|
|
114
|
+
title={widget.title}
|
|
115
|
+
roleSlug={roleSlugs[0]}
|
|
116
|
+
width={widget.width}
|
|
117
|
+
height={widget.height}
|
|
118
|
+
data={data?.[widget.slug]}
|
|
119
|
+
style={{
|
|
120
|
+
gridColumn: `span ${Math.min(widget.width, 12)}`,
|
|
121
|
+
gridRow: `auto / span ${widget.height}`,
|
|
122
|
+
}}
|
|
123
|
+
/>
|
|
124
|
+
</React.Suspense>
|
|
125
|
+
);
|
|
126
|
+
})}
|
|
127
|
+
</div>
|
|
128
|
+
);
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export default DashboardLayout;
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget Registry - Mapa de widgets do dashboard
|
|
3
|
+
*
|
|
4
|
+
* Este arquivo centraliza todas as informações de widgets para o dashboard da operations.
|
|
5
|
+
* Os widgets são importados dinamicamente em runtime.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export interface WidgetInfo {
|
|
9
|
+
slug: string;
|
|
10
|
+
title: string;
|
|
11
|
+
component: string;
|
|
12
|
+
roleSlug: string;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
category: 'collaborator' | 'supervisor' | 'director';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Widgets para Colaboradores (7)
|
|
19
|
+
export const COLLABORATOR_WIDGETS: WidgetInfo[] = [
|
|
20
|
+
{
|
|
21
|
+
slug: 'my-hours-period-kpi',
|
|
22
|
+
title: 'Minhas Horas (Período)',
|
|
23
|
+
component: 'MyHoursPeriodKpi',
|
|
24
|
+
roleSlug: 'collaborator',
|
|
25
|
+
width: 6,
|
|
26
|
+
height: 2,
|
|
27
|
+
category: 'collaborator',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
slug: 'my-timesheet-status-kpi',
|
|
31
|
+
title: 'Status do Timesheet',
|
|
32
|
+
component: 'MyTimesheetStatusKpi',
|
|
33
|
+
roleSlug: 'collaborator',
|
|
34
|
+
width: 6,
|
|
35
|
+
height: 2,
|
|
36
|
+
category: 'collaborator',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
slug: 'my-project-allocations-kpi',
|
|
40
|
+
title: 'Minhas Alocações',
|
|
41
|
+
component: 'MyProjectAllocationsKpi',
|
|
42
|
+
roleSlug: 'collaborator',
|
|
43
|
+
width: 6,
|
|
44
|
+
height: 2,
|
|
45
|
+
category: 'collaborator',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
slug: 'my-open-requests-kpi',
|
|
49
|
+
title: 'Requisições Abertas',
|
|
50
|
+
component: 'MyOpenRequestsKpi',
|
|
51
|
+
roleSlug: 'collaborator',
|
|
52
|
+
width: 6,
|
|
53
|
+
height: 2,
|
|
54
|
+
category: 'collaborator',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
slug: 'my-weekly-journey',
|
|
58
|
+
title: 'Jornada Semanal',
|
|
59
|
+
component: 'MyWeeklyJourney',
|
|
60
|
+
roleSlug: 'collaborator',
|
|
61
|
+
width: 12,
|
|
62
|
+
height: 3,
|
|
63
|
+
category: 'collaborator',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
slug: 'my-relevant-deadlines',
|
|
67
|
+
title: 'Prazos Relevantes',
|
|
68
|
+
component: 'MyRelevantDeadlines',
|
|
69
|
+
roleSlug: 'collaborator',
|
|
70
|
+
width: 6,
|
|
71
|
+
height: 3,
|
|
72
|
+
category: 'collaborator',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
slug: 'my-pending-requests-list',
|
|
76
|
+
title: 'Requisições Pendentes',
|
|
77
|
+
component: 'MyPendingRequestsList',
|
|
78
|
+
roleSlug: 'collaborator',
|
|
79
|
+
width: 6,
|
|
80
|
+
height: 3,
|
|
81
|
+
category: 'collaborator',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
slug: 'my-quick-actions',
|
|
85
|
+
title: 'Ações Rápidas',
|
|
86
|
+
component: 'MyQuickActions',
|
|
87
|
+
roleSlug: 'collaborator',
|
|
88
|
+
width: 12,
|
|
89
|
+
height: 2,
|
|
90
|
+
category: 'collaborator',
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
|
|
94
|
+
// Widgets para Supervisores (7)
|
|
95
|
+
export const SUPERVISOR_WIDGETS: WidgetInfo[] = [
|
|
96
|
+
{
|
|
97
|
+
slug: 'team-pending-approvals-kpi',
|
|
98
|
+
title: 'Aprovações Pendentes',
|
|
99
|
+
component: 'TeamPendingApprovalsKpi',
|
|
100
|
+
roleSlug: 'supervisor',
|
|
101
|
+
width: 6,
|
|
102
|
+
height: 2,
|
|
103
|
+
category: 'supervisor',
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
slug: 'team-hours-kpi',
|
|
107
|
+
title: 'Horas do Time',
|
|
108
|
+
component: 'TeamHoursKpi',
|
|
109
|
+
roleSlug: 'supervisor',
|
|
110
|
+
width: 6,
|
|
111
|
+
height: 2,
|
|
112
|
+
category: 'supervisor',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
slug: 'team-capacity-kpi',
|
|
116
|
+
title: 'Capacidade do Time',
|
|
117
|
+
component: 'TeamCapacityKpi',
|
|
118
|
+
roleSlug: 'supervisor',
|
|
119
|
+
width: 6,
|
|
120
|
+
height: 2,
|
|
121
|
+
category: 'supervisor',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
slug: 'team-utilization-overview',
|
|
125
|
+
title: 'Utilização do Time',
|
|
126
|
+
component: 'TeamUtilizationOverview',
|
|
127
|
+
roleSlug: 'supervisor',
|
|
128
|
+
width: 6,
|
|
129
|
+
height: 2,
|
|
130
|
+
category: 'supervisor',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
slug: 'team-workload-alerts',
|
|
134
|
+
title: 'Alertas de Carga',
|
|
135
|
+
component: 'TeamWorkloadAlerts',
|
|
136
|
+
roleSlug: 'supervisor',
|
|
137
|
+
width: 12,
|
|
138
|
+
height: 3,
|
|
139
|
+
category: 'supervisor',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
slug: 'managed-projects-status',
|
|
143
|
+
title: 'Status dos Projetos',
|
|
144
|
+
component: 'ManagedProjectsStatus',
|
|
145
|
+
roleSlug: 'supervisor',
|
|
146
|
+
width: 6,
|
|
147
|
+
height: 3,
|
|
148
|
+
category: 'supervisor',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
slug: 'team-approval-queue',
|
|
152
|
+
title: 'Fila de Aprovações',
|
|
153
|
+
component: 'TeamApprovalQueue',
|
|
154
|
+
roleSlug: 'supervisor',
|
|
155
|
+
width: 6,
|
|
156
|
+
height: 3,
|
|
157
|
+
category: 'supervisor',
|
|
158
|
+
},
|
|
159
|
+
];
|
|
160
|
+
|
|
161
|
+
// Widgets para Diretores (8)
|
|
162
|
+
export const DIRECTOR_WIDGETS: WidgetInfo[] = [
|
|
163
|
+
{
|
|
164
|
+
slug: 'portfolio-costs-kpi',
|
|
165
|
+
title: 'Custos do Portfólio',
|
|
166
|
+
component: 'PortfolioCostsKpi',
|
|
167
|
+
roleSlug: 'director',
|
|
168
|
+
width: 6,
|
|
169
|
+
height: 2,
|
|
170
|
+
category: 'director',
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
slug: 'portfolio-effort-kpi',
|
|
174
|
+
title: 'Esforço do Portfólio',
|
|
175
|
+
component: 'PortfolioEffortKpi',
|
|
176
|
+
roleSlug: 'director',
|
|
177
|
+
width: 6,
|
|
178
|
+
height: 2,
|
|
179
|
+
category: 'director',
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
slug: 'portfolio-risk-kpi',
|
|
183
|
+
title: 'Risco do Portfólio',
|
|
184
|
+
component: 'PortfolioRiskKpi',
|
|
185
|
+
roleSlug: 'director',
|
|
186
|
+
width: 6,
|
|
187
|
+
height: 2,
|
|
188
|
+
category: 'director',
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
slug: 'project-status-overview',
|
|
192
|
+
title: 'Status dos Projetos',
|
|
193
|
+
component: 'ProjectStatusOverview',
|
|
194
|
+
roleSlug: 'director',
|
|
195
|
+
width: 6,
|
|
196
|
+
height: 2,
|
|
197
|
+
category: 'director',
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
slug: 'effort-by-project',
|
|
201
|
+
title: 'Esforço por Projeto',
|
|
202
|
+
component: 'EffortByProject',
|
|
203
|
+
roleSlug: 'director',
|
|
204
|
+
width: 12,
|
|
205
|
+
height: 3,
|
|
206
|
+
category: 'director',
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
slug: 'capacity-distribution',
|
|
210
|
+
title: 'Distribuição de Capacidade',
|
|
211
|
+
component: 'CapacityDistribution',
|
|
212
|
+
roleSlug: 'director',
|
|
213
|
+
width: 6,
|
|
214
|
+
height: 3,
|
|
215
|
+
category: 'director',
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
slug: 'headcount-by-area',
|
|
219
|
+
title: 'Headcount por Área',
|
|
220
|
+
component: 'HeadcountByArea',
|
|
221
|
+
roleSlug: 'director',
|
|
222
|
+
width: 6,
|
|
223
|
+
height: 3,
|
|
224
|
+
category: 'director',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
slug: 'strategic-deadlines',
|
|
228
|
+
title: 'Prazos Estratégicos',
|
|
229
|
+
component: 'StrategicDeadlines',
|
|
230
|
+
roleSlug: 'director',
|
|
231
|
+
width: 12,
|
|
232
|
+
height: 3,
|
|
233
|
+
category: 'director',
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
|
|
237
|
+
// Registro completo de todos os widgets
|
|
238
|
+
export const ALL_WIDGETS = [
|
|
239
|
+
...COLLABORATOR_WIDGETS,
|
|
240
|
+
...SUPERVISOR_WIDGETS,
|
|
241
|
+
...DIRECTOR_WIDGETS,
|
|
242
|
+
];
|
|
243
|
+
|
|
244
|
+
// Acessores úteis
|
|
245
|
+
export const getWidgetsByRole = (roleSlug: string): WidgetInfo[] => {
|
|
246
|
+
return ALL_WIDGETS.filter(w => w.roleSlug === roleSlug);
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export const getWidgetBySlug = (slug: string): WidgetInfo | undefined => {
|
|
250
|
+
return ALL_WIDGETS.find(w => w.slug === slug);
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
export const getWidgetsByCategory = (category: 'collaborator' | 'supervisor' | 'director'): WidgetInfo[] => {
|
|
254
|
+
return ALL_WIDGETS.filter(w => w.category === category);
|
|
255
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook para buscar dados do dashboard de operations
|
|
3
|
+
* Cacheia dados por 60s usando react-query
|
|
4
|
+
* Filtra automaticamente por role do usuário
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import type { OperationsDashboardData } from '../types/widgets.types';
|
|
8
|
+
|
|
9
|
+
type DashboardRequestFn = <T extends object>(config: {
|
|
10
|
+
url: string;
|
|
11
|
+
method: 'GET';
|
|
12
|
+
}) => Promise<{ data: T }>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Loader enxuto para o payload agregado do dashboard.
|
|
16
|
+
* A camada de UI pode embrulhar isso em react-query sem repetir o contrato.
|
|
17
|
+
*/
|
|
18
|
+
export async function fetchDashboardData(request: DashboardRequestFn) {
|
|
19
|
+
const response = await request<OperationsDashboardData>({
|
|
20
|
+
url: '/operations/dashboard',
|
|
21
|
+
method: 'GET',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return response.data;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function useDashboardData(request: DashboardRequestFn) {
|
|
28
|
+
return fetchDashboardData(request);
|
|
29
|
+
}
|