@hed-hog/operations 0.0.302 → 0.0.304

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.
Files changed (167) hide show
  1. package/README.md +200 -43
  2. package/dist/controllers/operations-approvals.controller.d.ts +9 -0
  3. package/dist/controllers/operations-approvals.controller.d.ts.map +1 -0
  4. package/dist/controllers/operations-approvals.controller.js +64 -0
  5. package/dist/controllers/operations-approvals.controller.js.map +1 -0
  6. package/dist/controllers/operations-collaborators.controller.d.ts +223 -0
  7. package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -0
  8. package/dist/controllers/operations-collaborators.controller.js +96 -0
  9. package/dist/controllers/operations-collaborators.controller.js.map +1 -0
  10. package/dist/controllers/operations-contracts.controller.d.ts +683 -0
  11. package/dist/controllers/operations-contracts.controller.d.ts.map +1 -0
  12. package/dist/controllers/operations-contracts.controller.js +198 -0
  13. package/dist/controllers/operations-contracts.controller.js.map +1 -0
  14. package/dist/controllers/operations-org-structure.controller.d.ts +108 -0
  15. package/dist/controllers/operations-org-structure.controller.d.ts.map +1 -0
  16. package/dist/controllers/operations-org-structure.controller.js +143 -0
  17. package/dist/controllers/operations-org-structure.controller.js.map +1 -0
  18. package/dist/controllers/operations-projects.controller.d.ts +169 -0
  19. package/dist/controllers/operations-projects.controller.d.ts.map +1 -0
  20. package/dist/controllers/operations-projects.controller.js +87 -0
  21. package/dist/controllers/operations-projects.controller.js.map +1 -0
  22. package/dist/controllers/operations-tasks.controller.d.ts +54 -0
  23. package/dist/controllers/operations-tasks.controller.d.ts.map +1 -0
  24. package/dist/controllers/operations-tasks.controller.js +79 -0
  25. package/dist/controllers/operations-tasks.controller.js.map +1 -0
  26. package/dist/controllers/operations-timesheets.controller.d.ts +99 -0
  27. package/dist/controllers/operations-timesheets.controller.d.ts.map +1 -0
  28. package/dist/controllers/operations-timesheets.controller.js +154 -0
  29. package/dist/controllers/operations-timesheets.controller.js.map +1 -0
  30. package/dist/dto/create-collaborator-type.dto.d.ts +10 -0
  31. package/dist/dto/create-collaborator-type.dto.d.ts.map +1 -0
  32. package/dist/dto/create-collaborator-type.dto.js +56 -0
  33. package/dist/dto/create-collaborator-type.dto.js.map +1 -0
  34. package/dist/dto/create-collaborator.dto.d.ts +42 -0
  35. package/dist/dto/create-collaborator.dto.d.ts.map +1 -0
  36. package/dist/dto/create-collaborator.dto.js +228 -0
  37. package/dist/dto/create-collaborator.dto.js.map +1 -0
  38. package/dist/dto/create-schedule-adjustment-request.dto.d.ts +17 -0
  39. package/dist/dto/create-schedule-adjustment-request.dto.d.ts.map +1 -0
  40. package/dist/dto/create-schedule-adjustment-request.dto.js +89 -0
  41. package/dist/dto/create-schedule-adjustment-request.dto.js.map +1 -0
  42. package/dist/dto/create-task.dto.d.ts +8 -0
  43. package/dist/dto/create-task.dto.d.ts.map +1 -0
  44. package/dist/dto/create-task.dto.js +50 -0
  45. package/dist/dto/create-task.dto.js.map +1 -0
  46. package/dist/dto/create-time-off-request.dto.d.ts +9 -0
  47. package/dist/dto/create-time-off-request.dto.d.ts.map +1 -0
  48. package/dist/dto/create-time-off-request.dto.js +54 -0
  49. package/dist/dto/create-time-off-request.dto.js.map +1 -0
  50. package/dist/dto/create-timesheet-entry.dto.d.ts +12 -0
  51. package/dist/dto/create-timesheet-entry.dto.d.ts.map +1 -0
  52. package/dist/dto/create-timesheet-entry.dto.js +75 -0
  53. package/dist/dto/create-timesheet-entry.dto.js.map +1 -0
  54. package/dist/dto/list-collaborator-types.dto.d.ts +4 -0
  55. package/dist/dto/list-collaborator-types.dto.d.ts.map +1 -0
  56. package/dist/dto/list-collaborator-types.dto.js +29 -0
  57. package/dist/dto/list-collaborator-types.dto.js.map +1 -0
  58. package/dist/dto/list-collaborators.dto.d.ts +8 -0
  59. package/dist/dto/list-collaborators.dto.d.ts.map +1 -0
  60. package/dist/dto/list-collaborators.dto.js +42 -0
  61. package/dist/dto/list-collaborators.dto.js.map +1 -0
  62. package/dist/dto/list-project-options.dto.d.ts +4 -0
  63. package/dist/dto/list-project-options.dto.d.ts.map +1 -0
  64. package/dist/dto/list-project-options.dto.js +8 -0
  65. package/dist/dto/list-project-options.dto.js.map +1 -0
  66. package/dist/dto/list-tasks.dto.d.ts +7 -0
  67. package/dist/dto/list-tasks.dto.d.ts.map +1 -0
  68. package/dist/dto/list-tasks.dto.js +38 -0
  69. package/dist/dto/list-tasks.dto.js.map +1 -0
  70. package/dist/dto/list-timesheet-entries.dto.d.ts +10 -0
  71. package/dist/dto/list-timesheet-entries.dto.d.ts.map +1 -0
  72. package/dist/dto/list-timesheet-entries.dto.js +54 -0
  73. package/dist/dto/list-timesheet-entries.dto.js.map +1 -0
  74. package/dist/dto/update-collaborator-type.dto.d.ts +4 -0
  75. package/dist/dto/update-collaborator-type.dto.d.ts.map +1 -0
  76. package/dist/dto/update-collaborator-type.dto.js +8 -0
  77. package/dist/dto/update-collaborator-type.dto.js.map +1 -0
  78. package/dist/dto/update-collaborator.dto.d.ts +4 -0
  79. package/dist/dto/update-collaborator.dto.d.ts.map +1 -0
  80. package/dist/dto/update-collaborator.dto.js +8 -0
  81. package/dist/dto/update-collaborator.dto.js.map +1 -0
  82. package/dist/dto/update-task.dto.d.ts +8 -0
  83. package/dist/dto/update-task.dto.d.ts.map +1 -0
  84. package/dist/dto/update-task.dto.js +51 -0
  85. package/dist/dto/update-task.dto.js.map +1 -0
  86. package/dist/operations.controller.d.ts +0 -1045
  87. package/dist/operations.controller.d.ts.map +1 -1
  88. package/dist/operations.controller.js +0 -429
  89. package/dist/operations.controller.js.map +1 -1
  90. package/dist/operations.module.d.ts.map +1 -1
  91. package/dist/operations.module.js +23 -2
  92. package/dist/operations.module.js.map +1 -1
  93. package/dist/operations.service.d.ts +373 -8
  94. package/dist/operations.service.d.ts.map +1 -1
  95. package/dist/operations.service.js +1598 -111
  96. package/dist/operations.service.js.map +1 -1
  97. package/dist/operations.service.spec.js +315 -1
  98. package/dist/operations.service.spec.js.map +1 -1
  99. package/dist/services/shared/operations-access.service.d.ts +16 -0
  100. package/dist/services/shared/operations-access.service.d.ts.map +1 -0
  101. package/dist/services/shared/operations-access.service.js +48 -0
  102. package/dist/services/shared/operations-access.service.js.map +1 -0
  103. package/hedhog/data/dashboard.yaml +20 -0
  104. package/hedhog/data/dashboard_component.yaml +274 -0
  105. package/hedhog/data/dashboard_component_role.yaml +174 -0
  106. package/hedhog/data/dashboard_item.yaml +299 -0
  107. package/hedhog/data/dashboard_role.yaml +20 -0
  108. package/hedhog/data/menu.yaml +30 -13
  109. package/hedhog/data/operations_collaborator_type.yaml +76 -0
  110. package/hedhog/data/route.yaml +183 -0
  111. package/hedhog/frontend/app/_components/async-options-combobox.tsx.ejs +231 -0
  112. package/hedhog/frontend/app/_components/collaborator-details-screen.tsx.ejs +134 -49
  113. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +772 -93
  114. package/hedhog/frontend/app/_components/department-select-with-create.tsx.ejs +38 -16
  115. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +875 -632
  116. package/hedhog/frontend/app/_components/timesheet-task-create-sheet.tsx.ejs +213 -0
  117. package/hedhog/frontend/app/_lib/api.ts.ejs +30 -1
  118. package/hedhog/frontend/app/_lib/types.ts.ejs +142 -39
  119. package/hedhog/frontend/app/_lib/utils/format.ts.ejs +33 -2
  120. package/hedhog/frontend/app/approvals/page.tsx.ejs +116 -98
  121. package/hedhog/frontend/app/collaborator-types/page.tsx.ejs +502 -0
  122. package/hedhog/frontend/app/collaborators/page.tsx.ejs +109 -68
  123. package/hedhog/frontend/app/contracts/page.tsx.ejs +99 -102
  124. package/hedhog/frontend/app/contracts/templates/page.tsx.ejs +98 -102
  125. package/hedhog/frontend/app/departments/page.tsx.ejs +96 -75
  126. package/hedhog/frontend/app/projects/page.tsx.ejs +137 -127
  127. package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +244 -120
  128. package/hedhog/frontend/app/team/page.tsx.ejs +15 -2
  129. package/hedhog/frontend/app/time-off/page.tsx.ejs +158 -82
  130. package/hedhog/frontend/app/timesheets/page.tsx.ejs +814 -357
  131. package/hedhog/frontend/messages/en.json +243 -51
  132. package/hedhog/frontend/messages/pt.json +458 -268
  133. package/hedhog/table/operations_collaborator.yaml +26 -13
  134. package/hedhog/table/operations_collaborator_equity_participation.yaml +43 -0
  135. package/hedhog/table/operations_collaborator_type.yaml +33 -0
  136. package/hedhog/table/operations_job_title.yaml +24 -0
  137. package/hedhog/table/operations_project_assignment.yaml +9 -0
  138. package/hedhog/table/operations_project_role.yaml +39 -0
  139. package/hedhog/table/operations_task.yaml +30 -0
  140. package/hedhog/table/operations_timesheet_entry.yaml +12 -0
  141. package/package.json +6 -6
  142. package/src/controllers/operations-approvals.controller.ts +24 -0
  143. package/src/controllers/operations-collaborators.controller.ts +60 -0
  144. package/src/controllers/operations-contracts.controller.ts +138 -0
  145. package/src/controllers/operations-org-structure.controller.ts +92 -0
  146. package/src/controllers/operations-projects.controller.ts +50 -0
  147. package/src/controllers/operations-tasks.controller.ts +52 -0
  148. package/src/controllers/operations-timesheets.controller.ts +100 -0
  149. package/src/dto/create-collaborator-type.dto.ts +43 -0
  150. package/src/dto/create-collaborator.dto.ts +223 -0
  151. package/src/dto/create-schedule-adjustment-request.dto.ts +91 -0
  152. package/src/dto/create-task.dto.ts +35 -0
  153. package/src/dto/create-time-off-request.dto.ts +53 -0
  154. package/src/dto/create-timesheet-entry.dto.ts +67 -0
  155. package/src/dto/list-collaborator-types.dto.ts +15 -0
  156. package/src/dto/list-collaborators.dto.ts +30 -0
  157. package/src/dto/list-project-options.dto.ts +3 -0
  158. package/src/dto/list-tasks.dto.ts +25 -0
  159. package/src/dto/list-timesheet-entries.dto.ts +40 -0
  160. package/src/dto/update-collaborator-type.dto.ts +3 -0
  161. package/src/dto/update-collaborator.dto.ts +3 -0
  162. package/src/dto/update-task.dto.ts +36 -0
  163. package/src/operations.controller.ts +1 -278
  164. package/src/operations.module.ts +23 -2
  165. package/src/operations.service.spec.ts +450 -0
  166. package/src/operations.service.ts +4641 -2163
  167. package/src/services/shared/operations-access.service.ts +52 -0
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { EmptyState, Page, SearchBar } from '@/components/entity-list';
4
4
  import { Button } from '@/components/ui/button';
5
- import { Card, CardContent } from '@/components/ui/card';
6
5
  import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
7
6
  import {
8
7
  Sheet,
@@ -65,7 +64,10 @@ export default function OperationsProjectsPage() {
65
64
  const editProjectId = parseEditProjectId(searchParams.get('edit'));
66
65
  const isSheetOpen = createParam === '1' || editProjectId !== null;
67
66
 
68
- const updateSheetQuery = (next: { create?: boolean; editId?: number | null }) => {
67
+ const updateSheetQuery = (next: {
68
+ create?: boolean;
69
+ editId?: number | null;
70
+ }) => {
69
71
  const params = new URLSearchParams(searchParams.toString());
70
72
 
71
73
  params.delete('create');
@@ -117,7 +119,9 @@ export default function OperationsProjectsPage() {
117
119
  ]
118
120
  .filter(Boolean)
119
121
  .some((value) =>
120
- String(value).toLowerCase().includes(search.trim().toLowerCase())
122
+ String(value)
123
+ .toLowerCase()
124
+ .includes(search.trim().toLowerCase())
121
125
  );
122
126
 
123
127
  const matchesStatus =
@@ -133,24 +137,28 @@ export default function OperationsProjectsPage() {
133
137
  {
134
138
  key: 'total',
135
139
  title: t('cards.total'),
140
+ description: t('cards.totalDescription'),
136
141
  value: projects.length,
137
142
  icon: FolderKanban,
138
143
  },
139
144
  {
140
145
  key: 'active',
141
146
  title: t('cards.active'),
147
+ description: t('cards.activeDescription'),
142
148
  value: projects.filter((item) => item.status === 'active').length,
143
149
  icon: PlayCircle,
144
150
  },
145
151
  {
146
152
  key: 'atRisk',
147
153
  title: t('cards.atRisk'),
154
+ description: t('cards.atRiskDescription'),
148
155
  value: projects.filter((item) => item.status === 'at_risk').length,
149
156
  icon: ShieldAlert,
150
157
  },
151
158
  {
152
159
  key: 'upcomingDeliveries',
153
160
  title: t('cards.upcomingDeliveries'),
161
+ description: t('cards.upcomingDeliveriesDescription'),
154
162
  value: projects.filter((item) => Boolean(item.endDate)).length,
155
163
  icon: CalendarDays,
156
164
  },
@@ -220,139 +228,141 @@ export default function OperationsProjectsPage() {
220
228
  />
221
229
 
222
230
  {filteredRows.length > 0 ? (
223
- <Card className="overflow-hidden border-border/60 py-0 shadow-sm">
224
- <CardContent className="p-0">
225
- <Table className="table-fixed">
226
- <TableHeader>
227
- <TableRow>
228
- <TableHead className="w-[30%]">
229
- {commonT('labels.project')}
230
- </TableHead>
231
- <TableHead>{commonT('labels.client')}</TableHead>
232
- <TableHead>{commonT('labels.status')}</TableHead>
233
- <TableHead className="hidden lg:table-cell">
234
- {commonT('labels.manager')}
235
- </TableHead>
236
- <TableHead className="hidden md:table-cell">
237
- {commonT('labels.teamSize')}
238
- </TableHead>
239
- <TableHead className="hidden xl:table-cell">
240
- {commonT('labels.startDate')}
241
- </TableHead>
242
- <TableHead className="hidden xl:table-cell">
243
- {commonT('labels.endDate')}
244
- </TableHead>
245
- <TableHead className="hidden 2xl:table-cell">
246
- {commonT('labels.contractStatus')}
247
- </TableHead>
248
- <TableHead className="w-30 text-right sm:w-42.5">
249
- {commonT('labels.actions')}
250
- </TableHead>
251
- </TableRow>
252
- </TableHeader>
253
- <TableBody>
254
- {filteredRows.map((project) => (
255
- <TableRow key={project.id} className="hover:bg-muted/30">
256
- <TableCell>
257
- <div className="min-w-0">
258
- <div className="truncate font-medium">{project.name}</div>
259
- <div className="truncate text-xs text-muted-foreground">
260
- {[project.code, project.myRoleLabel, project.contractName]
261
- .filter(Boolean)
262
- .join(' • ') || commonT('labels.notAvailable')}
263
- </div>
264
- </div>
265
- </TableCell>
266
- <TableCell>
267
- <div className="truncate">
268
- {project.clientName || commonT('labels.notAvailable')}
231
+ <div className="overflow-x-auto rounded-md border">
232
+ <Table className="table-fixed">
233
+ <TableHeader>
234
+ <TableRow>
235
+ <TableHead className="w-[30%]">
236
+ {commonT('labels.project')}
237
+ </TableHead>
238
+ <TableHead>{commonT('labels.client')}</TableHead>
239
+ <TableHead>{commonT('labels.status')}</TableHead>
240
+ <TableHead className="hidden lg:table-cell">
241
+ {commonT('labels.manager')}
242
+ </TableHead>
243
+ <TableHead className="hidden md:table-cell">
244
+ {commonT('labels.teamSize')}
245
+ </TableHead>
246
+ <TableHead className="hidden xl:table-cell">
247
+ {commonT('labels.startDate')}
248
+ </TableHead>
249
+ <TableHead className="hidden xl:table-cell">
250
+ {commonT('labels.endDate')}
251
+ </TableHead>
252
+ <TableHead className="hidden 2xl:table-cell">
253
+ {commonT('labels.contractStatus')}
254
+ </TableHead>
255
+ <TableHead className="w-30 text-right sm:w-42.5">
256
+ {commonT('labels.actions')}
257
+ </TableHead>
258
+ </TableRow>
259
+ </TableHeader>
260
+ <TableBody>
261
+ {filteredRows.map((project) => (
262
+ <TableRow key={project.id} className="cursor-pointer hover:bg-muted/30">
263
+ <TableCell>
264
+ <div className="min-w-0">
265
+ <div className="truncate font-medium">{project.name}</div>
266
+ <div className="truncate text-xs text-muted-foreground">
267
+ {[
268
+ project.code,
269
+ project.myRoleLabel,
270
+ project.contractName,
271
+ ]
272
+ .filter(Boolean)
273
+ .join(' • ') || commonT('labels.notAvailable')}
269
274
  </div>
270
- </TableCell>
271
- <TableCell>
275
+ </div>
276
+ </TableCell>
277
+ <TableCell>
278
+ <div className="truncate">
279
+ {project.clientName || commonT('labels.notAvailable')}
280
+ </div>
281
+ </TableCell>
282
+ <TableCell>
283
+ <StatusBadge
284
+ label={formatEnumLabel(project.status)}
285
+ className={getStatusBadgeClass(project.status)}
286
+ />
287
+ </TableCell>
288
+ <TableCell className="hidden lg:table-cell">
289
+ <div className="truncate">
290
+ {project.managerName || commonT('labels.notAssigned')}
291
+ </div>
292
+ </TableCell>
293
+ <TableCell className="hidden md:table-cell">
294
+ {project.teamSize ?? 0}
295
+ </TableCell>
296
+ <TableCell className="hidden xl:table-cell">
297
+ {formatDate(project.startDate)}
298
+ </TableCell>
299
+ <TableCell className="hidden xl:table-cell">
300
+ {formatDate(project.endDate)}
301
+ </TableCell>
302
+ <TableCell className="hidden 2xl:table-cell">
303
+ {project.contractStatus ? (
272
304
  <StatusBadge
273
- label={formatEnumLabel(project.status)}
274
- className={getStatusBadgeClass(project.status)}
305
+ label={formatEnumLabel(project.contractStatus)}
306
+ className={getStatusBadgeClass(project.contractStatus)}
275
307
  />
276
- </TableCell>
277
- <TableCell className="hidden lg:table-cell">
278
- <div className="truncate">
279
- {project.managerName || commonT('labels.notAssigned')}
280
- </div>
281
- </TableCell>
282
- <TableCell className="hidden md:table-cell">
283
- {project.teamSize ?? 0}
284
- </TableCell>
285
- <TableCell className="hidden xl:table-cell">
286
- {formatDate(project.startDate)}
287
- </TableCell>
288
- <TableCell className="hidden xl:table-cell">
289
- {formatDate(project.endDate)}
290
- </TableCell>
291
- <TableCell className="hidden 2xl:table-cell">
292
- {project.contractStatus ? (
293
- <StatusBadge
294
- label={formatEnumLabel(project.contractStatus)}
295
- className={getStatusBadgeClass(project.contractStatus)}
296
- />
297
- ) : (
298
- commonT('labels.notAssigned')
299
- )}
300
- </TableCell>
301
- <TableCell>
302
- <div className="flex flex-wrap justify-end gap-1.5 sm:gap-2">
303
- <Button variant="outline" size="icon" asChild>
304
- <Link href={`/operations/projects/${project.id}`}>
305
- <Eye className="size-4" />
306
- </Link>
307
- </Button>
308
- {access.isDirector ? (
309
- <Button
310
- variant="outline"
311
- size="icon"
312
- className="cursor-pointer"
313
- onClick={() => openEditSheet(project.id)}
314
- >
315
- <Pencil className="size-4" />
316
- </Button>
317
- ) : null}
308
+ ) : (
309
+ commonT('labels.notAssigned')
310
+ )}
311
+ </TableCell>
312
+ <TableCell>
313
+ <div className="flex flex-wrap justify-end gap-1.5 sm:gap-2">
314
+ <Button variant="outline" size="icon" asChild>
315
+ <Link href={`/operations/projects/${project.id}`}>
316
+ <Eye className="size-4" />
317
+ </Link>
318
+ </Button>
319
+ {access.isDirector ? (
318
320
  <Button
319
321
  variant="outline"
320
322
  size="icon"
321
- asChild={Boolean(project.contractId)}
322
- disabled={!project.contractId}
323
+ className="cursor-pointer"
324
+ onClick={() => openEditSheet(project.id)}
323
325
  >
324
- {project.contractId ? (
325
- <Link
326
- href={`/operations/contracts?edit=${project.contractId}`}
327
- >
328
- <FileText className="size-4" />
329
- </Link>
330
- ) : (
331
- <span>
332
- <FileText className="size-4" />
333
- </span>
334
- )}
326
+ <Pencil className="size-4" />
335
327
  </Button>
336
- {access.isDirector ? (
337
- <Button
338
- variant="outline"
339
- size="sm"
340
- className="cursor-pointer"
341
- onClick={() => void toggleArchived(project)}
328
+ ) : null}
329
+ <Button
330
+ variant="outline"
331
+ size="icon"
332
+ asChild={Boolean(project.contractId)}
333
+ disabled={!project.contractId}
334
+ >
335
+ {project.contractId ? (
336
+ <Link
337
+ href={`/operations/contracts?edit=${project.contractId}`}
342
338
  >
343
- {project.status === 'archived'
344
- ? commonT('actions.activate')
345
- : t('actions.archive')}
346
- </Button>
347
- ) : null}
348
- </div>
349
- </TableCell>
350
- </TableRow>
351
- ))}
352
- </TableBody>
353
- </Table>
354
- </CardContent>
355
- </Card>
339
+ <FileText className="size-4" />
340
+ </Link>
341
+ ) : (
342
+ <span>
343
+ <FileText className="size-4" />
344
+ </span>
345
+ )}
346
+ </Button>
347
+ {access.isDirector ? (
348
+ <Button
349
+ variant="outline"
350
+ size="sm"
351
+ className="cursor-pointer"
352
+ onClick={() => void toggleArchived(project)}
353
+ >
354
+ {project.status === 'archived'
355
+ ? commonT('actions.activate')
356
+ : t('actions.archive')}
357
+ </Button>
358
+ ) : null}
359
+ </div>
360
+ </TableCell>
361
+ </TableRow>
362
+ ))}
363
+ </TableBody>
364
+ </Table>
365
+ </div>
356
366
  ) : (
357
367
  <EmptyState
358
368
  icon={<FolderKanban className="size-12" />}