@hed-hog/finance 0.0.236 → 0.0.237
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/hedhog/frontend/app/_components/person-field-with-create.tsx.ejs +627 -0
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +865 -883
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +838 -861
- package/hedhog/frontend/app/administration/categories/page.tsx.ejs +108 -25
- package/hedhog/frontend/app/administration/cost-centers/page.tsx.ejs +15 -8
- package/package.json +5 -5
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
import {
|
|
47
47
|
DndContext,
|
|
48
48
|
DragEndEvent,
|
|
49
|
+
DragOverEvent,
|
|
49
50
|
PointerSensor,
|
|
50
51
|
closestCenter,
|
|
51
52
|
useSensor,
|
|
@@ -53,7 +54,6 @@ import {
|
|
|
53
54
|
} from '@dnd-kit/core';
|
|
54
55
|
import {
|
|
55
56
|
SortableContext,
|
|
56
|
-
arrayMove,
|
|
57
57
|
useSortable,
|
|
58
58
|
verticalListSortingStrategy,
|
|
59
59
|
} from '@dnd-kit/sortable';
|
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
Trash2,
|
|
70
70
|
} from 'lucide-react';
|
|
71
71
|
import { useTranslations } from 'next-intl';
|
|
72
|
-
import { useMemo, useState } from 'react';
|
|
72
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
73
73
|
import { useForm } from 'react-hook-form';
|
|
74
74
|
import { z } from 'zod';
|
|
75
75
|
|
|
@@ -157,11 +157,8 @@ function CategoriaSheet({
|
|
|
157
157
|
},
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (!nextOpen) {
|
|
164
|
-
setEditing(null);
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
if (!open) {
|
|
165
162
|
form.reset({ nome: '', natureza: 'despesa', parentId: 'root' });
|
|
166
163
|
return;
|
|
167
164
|
}
|
|
@@ -172,6 +169,18 @@ function CategoriaSheet({
|
|
|
172
169
|
natureza: editing.natureza,
|
|
173
170
|
parentId: editing.parentId || 'root',
|
|
174
171
|
});
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
form.reset({ nome: '', natureza: 'despesa', parentId: 'root' });
|
|
176
|
+
}, [open, editing, form]);
|
|
177
|
+
|
|
178
|
+
const handleOpenChange = (nextOpen: boolean) => {
|
|
179
|
+
onOpenChange(nextOpen);
|
|
180
|
+
|
|
181
|
+
if (!nextOpen) {
|
|
182
|
+
setEditing(null);
|
|
183
|
+
form.reset({ nome: '', natureza: 'despesa', parentId: 'root' });
|
|
175
184
|
}
|
|
176
185
|
};
|
|
177
186
|
|
|
@@ -254,7 +263,7 @@ function CategoriaSheet({
|
|
|
254
263
|
<FormLabel>{t('sheet.fields.kind')}</FormLabel>
|
|
255
264
|
<Select value={field.value} onValueChange={field.onChange}>
|
|
256
265
|
<FormControl>
|
|
257
|
-
<SelectTrigger>
|
|
266
|
+
<SelectTrigger className="w-full">
|
|
258
267
|
<SelectValue placeholder={t('common.select')} />
|
|
259
268
|
</SelectTrigger>
|
|
260
269
|
</FormControl>
|
|
@@ -292,7 +301,7 @@ function CategoriaSheet({
|
|
|
292
301
|
onValueChange={field.onChange}
|
|
293
302
|
>
|
|
294
303
|
<FormControl>
|
|
295
|
-
<SelectTrigger>
|
|
304
|
+
<SelectTrigger className="w-full">
|
|
296
305
|
<SelectValue placeholder={t('sheet.fields.noParent')} />
|
|
297
306
|
</SelectTrigger>
|
|
298
307
|
</FormControl>
|
|
@@ -339,6 +348,7 @@ function CategoryRow({
|
|
|
339
348
|
setExpanded,
|
|
340
349
|
onEdit,
|
|
341
350
|
onDelete,
|
|
351
|
+
dropHint,
|
|
342
352
|
t,
|
|
343
353
|
}: {
|
|
344
354
|
item: CategoryNode & { level: number };
|
|
@@ -346,6 +356,7 @@ function CategoryRow({
|
|
|
346
356
|
setExpanded: (value: Set<string>) => void;
|
|
347
357
|
onEdit: (item: FinanceCategory) => void;
|
|
348
358
|
onDelete: (id: string) => void;
|
|
359
|
+
dropHint?: 'inside' | 'before' | 'after';
|
|
349
360
|
t: ReturnType<typeof useTranslations>;
|
|
350
361
|
}) {
|
|
351
362
|
const sortable = useSortable({ id: item.id });
|
|
@@ -363,7 +374,11 @@ function CategoryRow({
|
|
|
363
374
|
<div
|
|
364
375
|
ref={sortable.setNodeRef}
|
|
365
376
|
style={style}
|
|
366
|
-
className=
|
|
377
|
+
className={`rounded-md border bg-background ${
|
|
378
|
+
dropHint === 'inside' ? 'ring-1 ring-primary/50 bg-muted/40' : ''
|
|
379
|
+
} ${dropHint === 'before' ? 'border-t-2 border-t-primary' : ''} ${
|
|
380
|
+
dropHint === 'after' ? 'border-b-2 border-b-primary' : ''
|
|
381
|
+
}`}
|
|
367
382
|
>
|
|
368
383
|
<div
|
|
369
384
|
className="flex items-center justify-between gap-2 p-3"
|
|
@@ -439,6 +454,10 @@ export default function CategoriesPage() {
|
|
|
439
454
|
const [editing, setEditing] = useState<FinanceCategory | null>(null);
|
|
440
455
|
const [deleteId, setDeleteId] = useState<string | null>(null);
|
|
441
456
|
const [expanded, setExpanded] = useState<Set<string>>(new Set());
|
|
457
|
+
const [dragOverHint, setDragOverHint] = useState<{
|
|
458
|
+
overId: string;
|
|
459
|
+
mode: 'inside' | 'before' | 'after';
|
|
460
|
+
} | null>(null);
|
|
442
461
|
|
|
443
462
|
const sensors = useSensors(
|
|
444
463
|
useSensor(PointerSensor, { activationConstraint: { distance: 6 } })
|
|
@@ -492,27 +511,42 @@ export default function CategoriesPage() {
|
|
|
492
511
|
const activeId = String(active.id);
|
|
493
512
|
const overId = String(over.id);
|
|
494
513
|
|
|
495
|
-
const
|
|
496
|
-
const
|
|
514
|
+
const overRect = over.rect;
|
|
515
|
+
const activeTop =
|
|
516
|
+
active.rect.current.translated?.top ?? active.rect.current.initial?.top;
|
|
497
517
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
518
|
+
const isDropInsideTarget =
|
|
519
|
+
typeof activeTop === 'number' &&
|
|
520
|
+
activeTop > overRect.top + overRect.height * 0.25 &&
|
|
521
|
+
activeTop < overRect.top + overRect.height * 0.75;
|
|
501
522
|
|
|
502
|
-
const
|
|
503
|
-
const
|
|
504
|
-
|
|
505
|
-
|
|
523
|
+
const overParentId = idToParent.get(overId) || null;
|
|
524
|
+
const targetParentId = isDropInsideTarget ? overId : overParentId;
|
|
525
|
+
|
|
526
|
+
let cursor: string | null = targetParentId;
|
|
527
|
+
while (cursor) {
|
|
528
|
+
if (cursor === activeId) {
|
|
529
|
+
return;
|
|
530
|
+
}
|
|
531
|
+
cursor = idToParent.get(cursor) || null;
|
|
506
532
|
}
|
|
507
|
-
const targetParentId = idToParent.get(overId) || null;
|
|
508
533
|
|
|
509
|
-
const siblings =
|
|
534
|
+
const siblings = categories.filter(
|
|
510
535
|
(item) =>
|
|
511
|
-
(
|
|
512
|
-
item.id !== movedItem.id
|
|
536
|
+
(item.parentId || null) === targetParentId && item.id !== activeId
|
|
513
537
|
);
|
|
514
538
|
|
|
515
|
-
|
|
539
|
+
let position = siblings.length;
|
|
540
|
+
|
|
541
|
+
if (!isDropInsideTarget) {
|
|
542
|
+
const overIndex = siblings.findIndex((item) => item.id === overId);
|
|
543
|
+
if (overIndex !== -1) {
|
|
544
|
+
const isDropAfter =
|
|
545
|
+
typeof activeTop === 'number' &&
|
|
546
|
+
activeTop > overRect.top + overRect.height / 2;
|
|
547
|
+
position = isDropAfter ? overIndex + 1 : overIndex;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
516
550
|
|
|
517
551
|
try {
|
|
518
552
|
await request({
|
|
@@ -520,15 +554,57 @@ export default function CategoriesPage() {
|
|
|
520
554
|
method: 'PATCH',
|
|
521
555
|
data: {
|
|
522
556
|
parent_id: targetParentId ? Number(targetParentId) : null,
|
|
523
|
-
position
|
|
557
|
+
position,
|
|
524
558
|
},
|
|
525
559
|
});
|
|
526
560
|
|
|
527
561
|
await refetch();
|
|
562
|
+
if (targetParentId) {
|
|
563
|
+
setExpanded((prev) => {
|
|
564
|
+
const next = new Set(prev);
|
|
565
|
+
next.add(targetParentId);
|
|
566
|
+
return next;
|
|
567
|
+
});
|
|
568
|
+
}
|
|
528
569
|
showToastHandler?.('success', t('messages.moveSuccess'));
|
|
529
570
|
} catch {
|
|
530
571
|
showToastHandler?.('error', t('messages.moveError'));
|
|
572
|
+
} finally {
|
|
573
|
+
setDragOverHint(null);
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
|
|
577
|
+
const handleDragOver = (event: DragOverEvent) => {
|
|
578
|
+
const { active, over } = event;
|
|
579
|
+
|
|
580
|
+
if (!over || active.id === over.id) {
|
|
581
|
+
setDragOverHint(null);
|
|
582
|
+
return;
|
|
531
583
|
}
|
|
584
|
+
|
|
585
|
+
const overRect = over.rect;
|
|
586
|
+
const activeTop =
|
|
587
|
+
active.rect.current.translated?.top ?? active.rect.current.initial?.top;
|
|
588
|
+
|
|
589
|
+
if (typeof activeTop !== 'number') {
|
|
590
|
+
setDragOverHint(null);
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
const overId = String(over.id);
|
|
595
|
+
const inside =
|
|
596
|
+
activeTop > overRect.top + overRect.height * 0.25 &&
|
|
597
|
+
activeTop < overRect.top + overRect.height * 0.75;
|
|
598
|
+
|
|
599
|
+
if (inside) {
|
|
600
|
+
setDragOverHint({ overId, mode: 'inside' });
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
setDragOverHint({
|
|
605
|
+
overId,
|
|
606
|
+
mode: activeTop > overRect.top + overRect.height / 2 ? 'after' : 'before',
|
|
607
|
+
});
|
|
532
608
|
};
|
|
533
609
|
|
|
534
610
|
return (
|
|
@@ -576,7 +652,9 @@ export default function CategoriesPage() {
|
|
|
576
652
|
<DndContext
|
|
577
653
|
sensors={sensors}
|
|
578
654
|
collisionDetection={closestCenter}
|
|
655
|
+
onDragOver={handleDragOver}
|
|
579
656
|
onDragEnd={handleDragEnd}
|
|
657
|
+
onDragCancel={() => setDragOverHint(null)}
|
|
580
658
|
>
|
|
581
659
|
<SortableContext
|
|
582
660
|
items={flat.map((item) => item.id)}
|
|
@@ -589,6 +667,11 @@ export default function CategoriesPage() {
|
|
|
589
667
|
item={item}
|
|
590
668
|
expanded={expanded}
|
|
591
669
|
setExpanded={setExpanded}
|
|
670
|
+
dropHint={
|
|
671
|
+
dragOverHint?.overId === item.id
|
|
672
|
+
? dragOverHint.mode
|
|
673
|
+
: undefined
|
|
674
|
+
}
|
|
592
675
|
onEdit={(category) => {
|
|
593
676
|
setEditing(category);
|
|
594
677
|
setSheetOpen(true);
|
|
@@ -40,7 +40,7 @@ import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
|
40
40
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
41
41
|
import { Building2, Pencil, Plus, Trash2 } from 'lucide-react';
|
|
42
42
|
import { useTranslations } from 'next-intl';
|
|
43
|
-
import { useState } from 'react';
|
|
43
|
+
import { useEffect, useState } from 'react';
|
|
44
44
|
import { useForm } from 'react-hook-form';
|
|
45
45
|
import { z } from 'zod';
|
|
46
46
|
|
|
@@ -84,6 +84,20 @@ function CentroCustoSheet({
|
|
|
84
84
|
},
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
if (!open) {
|
|
89
|
+
form.reset({ nome: '' });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (editingCostCenter) {
|
|
94
|
+
form.reset({ nome: editingCostCenter.nome });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
form.reset({ nome: '' });
|
|
99
|
+
}, [open, editingCostCenter, form]);
|
|
100
|
+
|
|
87
101
|
const handleSubmit = async (values: CostCenterFormValues) => {
|
|
88
102
|
try {
|
|
89
103
|
if (editingCostCenter) {
|
|
@@ -130,13 +144,6 @@ function CentroCustoSheet({
|
|
|
130
144
|
if (!nextOpen) {
|
|
131
145
|
form.reset({ nome: '' });
|
|
132
146
|
onEditingChange(null);
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (editingCostCenter) {
|
|
137
|
-
form.reset({
|
|
138
|
-
nome: editingCostCenter.nome,
|
|
139
|
-
});
|
|
140
147
|
}
|
|
141
148
|
};
|
|
142
149
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hed-hog/finance",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.237",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"dependencies": {
|
|
@@ -9,14 +9,14 @@
|
|
|
9
9
|
"@nestjs/core": "^11",
|
|
10
10
|
"@nestjs/jwt": "^11",
|
|
11
11
|
"@nestjs/mapped-types": "*",
|
|
12
|
-
"@hed-hog/api-locale": "0.0.11",
|
|
13
12
|
"@hed-hog/api-prisma": "0.0.4",
|
|
13
|
+
"@hed-hog/tag": "0.0.237",
|
|
14
14
|
"@hed-hog/api-pagination": "0.0.5",
|
|
15
15
|
"@hed-hog/api-types": "0.0.1",
|
|
16
|
-
"@hed-hog/tag": "0.0.236",
|
|
17
16
|
"@hed-hog/api": "0.0.3",
|
|
18
|
-
"@hed-hog/contact": "0.0.
|
|
19
|
-
"@hed-hog/core": "0.0.
|
|
17
|
+
"@hed-hog/contact": "0.0.237",
|
|
18
|
+
"@hed-hog/core": "0.0.237",
|
|
19
|
+
"@hed-hog/api-locale": "0.0.11"
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
22
22
|
".": {
|