@hed-hog/operations 0.0.306 → 0.0.310

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 (123) hide show
  1. package/dist/controllers/operations-approvals.controller.d.ts +114 -1
  2. package/dist/controllers/operations-approvals.controller.d.ts.map +1 -1
  3. package/dist/controllers/operations-approvals.controller.js +16 -3
  4. package/dist/controllers/operations-approvals.controller.js.map +1 -1
  5. package/dist/controllers/operations-collaborators.controller.d.ts +16 -1
  6. package/dist/controllers/operations-collaborators.controller.d.ts.map +1 -1
  7. package/dist/controllers/operations-collaborators.controller.js +16 -3
  8. package/dist/controllers/operations-collaborators.controller.js.map +1 -1
  9. package/dist/controllers/operations-contracts.controller.d.ts +14 -453
  10. package/dist/controllers/operations-contracts.controller.d.ts.map +1 -1
  11. package/dist/controllers/operations-contracts.controller.js +11 -112
  12. package/dist/controllers/operations-contracts.controller.js.map +1 -1
  13. package/dist/controllers/operations-org-structure.controller.d.ts +65 -2
  14. package/dist/controllers/operations-org-structure.controller.d.ts.map +1 -1
  15. package/dist/controllers/operations-org-structure.controller.js +18 -5
  16. package/dist/controllers/operations-org-structure.controller.js.map +1 -1
  17. package/dist/controllers/operations-projects.controller.d.ts +28 -4
  18. package/dist/controllers/operations-projects.controller.d.ts.map +1 -1
  19. package/dist/controllers/operations-projects.controller.js +17 -5
  20. package/dist/controllers/operations-projects.controller.js.map +1 -1
  21. package/dist/controllers/operations-timesheets.controller.d.ts +31 -4
  22. package/dist/controllers/operations-timesheets.controller.d.ts.map +1 -1
  23. package/dist/controllers/operations-timesheets.controller.js +16 -11
  24. package/dist/controllers/operations-timesheets.controller.js.map +1 -1
  25. package/dist/dto/list-approvals.dto.d.ts +6 -0
  26. package/dist/dto/list-approvals.dto.d.ts.map +1 -0
  27. package/dist/dto/list-approvals.dto.js +28 -0
  28. package/dist/dto/list-approvals.dto.js.map +1 -0
  29. package/dist/dto/list-collaborator-types.dto.d.ts +3 -1
  30. package/dist/dto/list-collaborator-types.dto.d.ts.map +1 -1
  31. package/dist/dto/list-collaborator-types.dto.js +7 -1
  32. package/dist/dto/list-collaborator-types.dto.js.map +1 -1
  33. package/dist/dto/list-collaborators.dto.d.ts +1 -0
  34. package/dist/dto/list-collaborators.dto.d.ts.map +1 -1
  35. package/dist/dto/list-collaborators.dto.js +5 -0
  36. package/dist/dto/list-collaborators.dto.js.map +1 -1
  37. package/dist/dto/list-contracts.dto.d.ts +8 -0
  38. package/dist/dto/list-contracts.dto.d.ts.map +1 -0
  39. package/dist/dto/list-contracts.dto.js +38 -0
  40. package/dist/dto/list-contracts.dto.js.map +1 -0
  41. package/dist/dto/list-departments.dto.d.ts +5 -0
  42. package/dist/dto/list-departments.dto.d.ts.map +1 -0
  43. package/dist/dto/list-departments.dto.js +23 -0
  44. package/dist/dto/list-departments.dto.js.map +1 -0
  45. package/dist/dto/list-projects.dto.d.ts +5 -0
  46. package/dist/dto/list-projects.dto.d.ts.map +1 -0
  47. package/dist/dto/list-projects.dto.js +23 -0
  48. package/dist/dto/list-projects.dto.js.map +1 -0
  49. package/dist/dto/list-schedule-adjustments.dto.d.ts +5 -0
  50. package/dist/dto/list-schedule-adjustments.dto.d.ts.map +1 -0
  51. package/dist/dto/list-schedule-adjustments.dto.js +23 -0
  52. package/dist/dto/list-schedule-adjustments.dto.js.map +1 -0
  53. package/dist/dto/list-time-off-requests.dto.d.ts +5 -0
  54. package/dist/dto/list-time-off-requests.dto.d.ts.map +1 -0
  55. package/dist/dto/list-time-off-requests.dto.js +23 -0
  56. package/dist/dto/list-time-off-requests.dto.js.map +1 -0
  57. package/dist/dto/list-timesheets.dto.d.ts +5 -0
  58. package/dist/dto/list-timesheets.dto.d.ts.map +1 -0
  59. package/dist/dto/list-timesheets.dto.js +23 -0
  60. package/dist/dto/list-timesheets.dto.js.map +1 -0
  61. package/dist/dto/reorder-collaborator-types.dto.d.ts +4 -0
  62. package/dist/dto/reorder-collaborator-types.dto.d.ts.map +1 -0
  63. package/dist/dto/reorder-collaborator-types.dto.js +25 -0
  64. package/dist/dto/reorder-collaborator-types.dto.js.map +1 -0
  65. package/dist/operations.service.d.ts +340 -271
  66. package/dist/operations.service.d.ts.map +1 -1
  67. package/dist/operations.service.js +1007 -1043
  68. package/dist/operations.service.js.map +1 -1
  69. package/dist/operations.service.spec.js +0 -22
  70. package/dist/operations.service.spec.js.map +1 -1
  71. package/hedhog/data/menu.yaml +0 -36
  72. package/hedhog/data/route.yaml +42 -73
  73. package/hedhog/frontend/app/_components/collaborator-form-screen.tsx.ejs +8 -1
  74. package/hedhog/frontend/app/_components/collaborator-select-with-create.tsx.ejs +15 -10
  75. package/hedhog/frontend/app/_components/contract-details-screen.tsx.ejs +108 -213
  76. package/hedhog/frontend/app/_components/contract-form-screen.tsx.ejs +251 -2039
  77. package/hedhog/frontend/app/_components/project-details-screen.tsx.ejs +167 -60
  78. package/hedhog/frontend/app/_components/project-form-screen.tsx.ejs +70 -301
  79. package/hedhog/frontend/app/_components/system-user-select-with-create.tsx.ejs +102 -51
  80. package/hedhog/frontend/app/_lib/types.ts.ejs +19 -24
  81. package/hedhog/frontend/app/_lib/utils/format.ts.ejs +14 -9
  82. package/hedhog/frontend/app/approvals/page.tsx.ejs +842 -150
  83. package/hedhog/frontend/app/collaborator-types/page.tsx.ejs +445 -153
  84. package/hedhog/frontend/app/collaborators/page.tsx.ejs +118 -49
  85. package/hedhog/frontend/app/contracts/[id]/page.tsx.ejs +2 -2
  86. package/hedhog/frontend/app/contracts/page.tsx.ejs +215 -617
  87. package/hedhog/frontend/app/departments/page.tsx.ejs +257 -113
  88. package/hedhog/frontend/app/projects/page.tsx.ejs +90 -51
  89. package/hedhog/frontend/app/schedule-adjustments/page.tsx.ejs +412 -147
  90. package/hedhog/frontend/app/time-off/page.tsx.ejs +400 -123
  91. package/hedhog/frontend/app/timesheets/page.tsx.ejs +460 -365
  92. package/hedhog/frontend/messages/en.json +143 -14
  93. package/hedhog/frontend/messages/pt.json +192 -54
  94. package/hedhog/table/operations_contract.yaml +0 -9
  95. package/package.json +4 -4
  96. package/src/controllers/operations-approvals.controller.ts +9 -3
  97. package/src/controllers/operations-collaborators.controller.ts +15 -2
  98. package/src/controllers/operations-contracts.controller.ts +8 -92
  99. package/src/controllers/operations-org-structure.controller.ts +17 -4
  100. package/src/controllers/operations-projects.controller.ts +10 -4
  101. package/src/controllers/operations-timesheets.controller.ts +17 -8
  102. package/src/dto/list-approvals.dto.ts +12 -0
  103. package/src/dto/list-collaborator-types.dto.ts +7 -2
  104. package/src/dto/list-collaborators.dto.ts +4 -0
  105. package/src/dto/list-contracts.dto.ts +20 -0
  106. package/src/dto/list-departments.dto.ts +8 -0
  107. package/src/dto/list-projects.dto.ts +8 -0
  108. package/src/dto/list-schedule-adjustments.dto.ts +8 -0
  109. package/src/dto/list-time-off-requests.dto.ts +8 -0
  110. package/src/dto/list-timesheets.dto.ts +8 -0
  111. package/src/dto/reorder-collaborator-types.dto.ts +10 -0
  112. package/src/operations.service.spec.ts +0 -30
  113. package/src/operations.service.ts +1557 -1806
  114. package/hedhog/frontend/app/_components/contract-creation-wizard.tsx.ejs +0 -631
  115. package/hedhog/frontend/app/_components/contract-template-form-screen.tsx.ejs +0 -526
  116. package/hedhog/frontend/app/_components/contract-template-select-with-create.tsx.ejs +0 -247
  117. package/hedhog/frontend/app/_components/contract-wizard-sheet.tsx.ejs +0 -3520
  118. package/hedhog/frontend/app/contracts/templates/page.tsx.ejs +0 -380
  119. package/hedhog/frontend/app/team/page.tsx.ejs +0 -352
  120. package/hedhog/table/operations_contract_financial_term.yaml +0 -40
  121. package/hedhog/table/operations_contract_revision.yaml +0 -38
  122. package/hedhog/table/operations_contract_signature.yaml +0 -38
  123. package/hedhog/table/operations_contract_template.yaml +0 -58
@@ -1,380 +0,0 @@
1
- 'use client';
2
-
3
- import { EmptyState, Page, SearchBar } from '@/components/entity-list';
4
- import { Button } from '@/components/ui/button';
5
- import { KpiCardsGrid } from '@/components/ui/kpi-cards-grid';
6
- import {
7
- Sheet,
8
- SheetContent,
9
- SheetDescription,
10
- SheetHeader,
11
- SheetTitle,
12
- } from '@/components/ui/sheet';
13
- import {
14
- Table,
15
- TableBody,
16
- TableCell,
17
- TableHead,
18
- TableHeader,
19
- TableRow,
20
- } from '@/components/ui/table';
21
- import { useApp, useQuery } from '@hed-hog/next-app-provider';
22
- import { FileStack, Pencil, Sparkles } from 'lucide-react';
23
- import { useTranslations } from 'next-intl';
24
- import Link from 'next/link';
25
- import { useMemo, useState } from 'react';
26
- import { ContractTemplateFormScreen } from '../../_components/contract-template-form-screen';
27
- import { OperationsHeader } from '../../_components/operations-header';
28
- import { StatusBadge } from '../../_components/status-badge';
29
- import { fetchOperations, mutateOperations } from '../../_lib/api';
30
- import { useOperationsAccess } from '../../_lib/hooks/use-operations-access';
31
- import type { OperationsContractTemplate } from '../../_lib/types';
32
- import {
33
- formatDate,
34
- formatEnumLabel,
35
- getStatusBadgeClass,
36
- } from '../../_lib/utils/format';
37
-
38
- export default function OperationsContractTemplatesPage() {
39
- const t = useTranslations('operations.ContractTemplatesPage');
40
- const commonT = useTranslations('operations.Common');
41
- const { request, showToastHandler, currentLocaleCode } = useApp();
42
- const access = useOperationsAccess();
43
- const [search, setSearch] = useState('');
44
- const [statusFilter, setStatusFilter] = useState('all');
45
- const [typeFilter, setTypeFilter] = useState('all');
46
- const [editingTemplate, setEditingTemplate] =
47
- useState<OperationsContractTemplate | null>(null);
48
- const [isSheetOpen, setIsSheetOpen] = useState(false);
49
-
50
- const {
51
- data: templates = [],
52
- isLoading,
53
- refetch,
54
- } = useQuery<OperationsContractTemplate[]>({
55
- queryKey: ['operations-contract-templates-list', currentLocaleCode],
56
- enabled: access.isDirector,
57
- queryFn: () =>
58
- fetchOperations<OperationsContractTemplate[]>(
59
- request,
60
- '/operations/contract-templates'
61
- ),
62
- });
63
-
64
- const filteredTemplates = useMemo(
65
- () =>
66
- templates.filter((template) => {
67
- const matchesSearch = !search.trim()
68
- ? true
69
- : [
70
- template.name,
71
- template.code,
72
- template.description,
73
- template.contractType,
74
- ]
75
- .filter(Boolean)
76
- .some((value) =>
77
- String(value)
78
- .toLowerCase()
79
- .includes(search.trim().toLowerCase())
80
- );
81
-
82
- const matchesStatus =
83
- statusFilter === 'all' ? true : template.status === statusFilter;
84
- const matchesType =
85
- typeFilter === 'all' ? true : template.contractType === typeFilter;
86
-
87
- return matchesSearch && matchesStatus && matchesType;
88
- }),
89
- [search, statusFilter, templates, typeFilter]
90
- );
91
-
92
- const statsCards = useMemo(
93
- () => [
94
- {
95
- key: 'total',
96
- title: t('cards.total'),
97
- value: templates.length,
98
- icon: FileStack,
99
- },
100
- {
101
- key: 'active',
102
- title: t('cards.active'),
103
- value: templates.filter((item) => item.status === 'active').length,
104
- icon: Sparkles,
105
- },
106
- {
107
- key: 'draft',
108
- title: t('cards.draft'),
109
- value: templates.filter((item) => item.status === 'draft').length,
110
- icon: FileStack,
111
- },
112
- {
113
- key: 'archived',
114
- title: t('cards.archived'),
115
- value: templates.filter((item) => item.status === 'archived').length,
116
- icon: FileStack,
117
- },
118
- ],
119
- [t, templates]
120
- );
121
-
122
- const openCreateSheet = () => {
123
- setEditingTemplate(null);
124
- setIsSheetOpen(true);
125
- };
126
-
127
- const openEditSheet = (template: OperationsContractTemplate) => {
128
- setEditingTemplate(template);
129
- setIsSheetOpen(true);
130
- };
131
-
132
- const toggleTemplateStatus = async (template: OperationsContractTemplate) => {
133
- const nextStatus =
134
- template.status === 'active'
135
- ? 'inactive'
136
- : template.status === 'archived'
137
- ? 'active'
138
- : 'active';
139
-
140
- try {
141
- await mutateOperations(
142
- request,
143
- `/operations/contract-templates/${template.id}`,
144
- 'PATCH',
145
- {
146
- status: nextStatus,
147
- isActive: nextStatus === 'active',
148
- }
149
- );
150
- showToastHandler?.('success', t('messages.statusSuccess'));
151
- await refetch();
152
- } catch {
153
- showToastHandler?.('error', t('messages.statusError'));
154
- }
155
- };
156
-
157
- if (!access.isLoading && !access.isDirector) {
158
- return (
159
- <Page>
160
- <OperationsHeader
161
- title={t('title')}
162
- description={t('description')}
163
- current={t('breadcrumb')}
164
- actions={
165
- <Button variant="outline" size="sm" asChild>
166
- <Link href="/operations/contracts">
167
- {commonT('actions.back')}
168
- </Link>
169
- </Button>
170
- }
171
- />
172
-
173
- <EmptyState
174
- icon={<FileStack className="size-12" />}
175
- title={commonT('states.noAccessTitle')}
176
- description={t('noAccessDescription')}
177
- actionLabel={commonT('actions.back')}
178
- onAction={() => {
179
- window.location.href = '/operations/contracts';
180
- }}
181
- />
182
- </Page>
183
- );
184
- }
185
-
186
- return (
187
- <Page>
188
- <OperationsHeader
189
- title={t('title')}
190
- description={t('description')}
191
- current={t('breadcrumb')}
192
- actions={
193
- <div className="flex flex-wrap gap-2">
194
- <Button variant="outline" size="sm" asChild>
195
- <Link href="/operations/contracts">
196
- {commonT('actions.back')}
197
- </Link>
198
- </Button>
199
- <Button
200
- size="sm"
201
- className="cursor-pointer"
202
- onClick={openCreateSheet}
203
- >
204
- {commonT('actions.create')}
205
- </Button>
206
- </div>
207
- }
208
- />
209
-
210
- <KpiCardsGrid items={statsCards} columns={4} />
211
-
212
- <SearchBar
213
- searchQuery={search}
214
- onSearchChange={setSearch}
215
- onSearch={() => undefined}
216
- placeholder={t('searchPlaceholder')}
217
- controls={[
218
- {
219
- id: 'type',
220
- type: 'select',
221
- value: typeFilter,
222
- onChange: setTypeFilter,
223
- placeholder: t('filters.type'),
224
- options: [
225
- { value: 'all', label: commonT('filters.allTypes') },
226
- ...[
227
- 'clt',
228
- 'pj',
229
- 'freelancer_agreement',
230
- 'service_agreement',
231
- 'fixed_term',
232
- 'recurring_service',
233
- 'nda',
234
- 'amendment',
235
- 'addendum',
236
- 'other',
237
- ].map((value) => ({ value, label: formatEnumLabel(value) })),
238
- ],
239
- },
240
- {
241
- id: 'status',
242
- type: 'select',
243
- value: statusFilter,
244
- onChange: setStatusFilter,
245
- placeholder: commonT('labels.status'),
246
- options: [
247
- { value: 'all', label: commonT('filters.allStatuses') },
248
- ...['active', 'draft', 'inactive', 'archived'].map((value) => ({
249
- value,
250
- label: formatEnumLabel(value),
251
- })),
252
- ],
253
- },
254
- ]}
255
- />
256
-
257
- {isLoading ? (
258
- <div className="rounded-md border px-4 py-6 text-sm text-muted-foreground">
259
- {commonT('actions.refresh')}...
260
- </div>
261
- ) : filteredTemplates.length ? (
262
- <div className="overflow-x-auto rounded-md border">
263
- <Table>
264
- <TableHeader>
265
- <TableRow>
266
- <TableHead>{t('columns.name')}</TableHead>
267
- <TableHead>{t('columns.code')}</TableHead>
268
- <TableHead>{t('columns.type')}</TableHead>
269
- <TableHead>{t('columns.usageCount')}</TableHead>
270
- <TableHead>{commonT('labels.billingModel')}</TableHead>
271
- <TableHead>{t('columns.updatedAt')}</TableHead>
272
- <TableHead>{commonT('labels.status')}</TableHead>
273
- <TableHead className="text-right">
274
- {commonT('labels.actions')}
275
- </TableHead>
276
- </TableRow>
277
- </TableHeader>
278
- <TableBody>
279
- {filteredTemplates.map((template) => (
280
- <TableRow key={template.id}>
281
- <TableCell>
282
- <div className="space-y-1">
283
- <div className="font-medium">{template.name}</div>
284
- <div className="max-w-md text-xs text-muted-foreground">
285
- {template.description || commonT('labels.notAvailable')}
286
- </div>
287
- </div>
288
- </TableCell>
289
- <TableCell>{template.code || '—'}</TableCell>
290
- <TableCell>
291
- {formatEnumLabel(template.contractType)}
292
- </TableCell>
293
- <TableCell>{template.usageCount ?? 0}</TableCell>
294
- <TableCell>
295
- {formatEnumLabel(template.billingModel)}
296
- </TableCell>
297
- <TableCell>{formatDate(template.updatedAt)}</TableCell>
298
- <TableCell>
299
- <StatusBadge
300
- label={formatEnumLabel(template.status)}
301
- className={getStatusBadgeClass(template.status)}
302
- />
303
- </TableCell>
304
- <TableCell>
305
- <div className="flex justify-end gap-2">
306
- <Button
307
- type="button"
308
- variant="outline"
309
- size="sm"
310
- className="cursor-pointer"
311
- asChild
312
- >
313
- <Link
314
- href={`/operations/contracts?template=${template.id}`}
315
- >
316
- {commonT('actions.useTemplate')}
317
- </Link>
318
- </Button>
319
- <Button
320
- type="button"
321
- variant="outline"
322
- size="icon"
323
- className="cursor-pointer"
324
- onClick={() => openEditSheet(template)}
325
- >
326
- <Pencil className="size-4" />
327
- </Button>
328
- <Button
329
- type="button"
330
- variant="outline"
331
- size="sm"
332
- className="cursor-pointer"
333
- onClick={() => void toggleTemplateStatus(template)}
334
- >
335
- {template.status === 'active'
336
- ? commonT('actions.deactivate')
337
- : commonT('actions.activate')}
338
- </Button>
339
- </div>
340
- </TableCell>
341
- </TableRow>
342
- ))}
343
- </TableBody>
344
- </Table>
345
- </div>
346
- ) : (
347
- <EmptyState
348
- icon={<FileStack className="size-12" />}
349
- title={commonT('states.emptyTitle')}
350
- description={t('emptyDescription')}
351
- actionLabel={commonT('actions.create')}
352
- onAction={openCreateSheet}
353
- />
354
- )}
355
-
356
- <Sheet open={isSheetOpen} onOpenChange={setIsSheetOpen}>
357
- <SheetContent className="w-full overflow-y-auto sm:max-w-6xl">
358
- <SheetHeader>
359
- <SheetTitle>
360
- {editingTemplate ? t('sheet.editTitle') : t('sheet.createTitle')}
361
- </SheetTitle>
362
- <SheetDescription>{t('sheet.description')}</SheetDescription>
363
- </SheetHeader>
364
-
365
- <div className="px-4">
366
- <ContractTemplateFormScreen
367
- templateId={editingTemplate?.id}
368
- onCancel={() => setIsSheetOpen(false)}
369
- onSaved={async () => {
370
- setIsSheetOpen(false);
371
- setEditingTemplate(null);
372
- await refetch();
373
- }}
374
- />
375
- </div>
376
- </SheetContent>
377
- </Sheet>
378
- </Page>
379
- );
380
- }