@hed-hog/finance 0.0.304 → 0.0.306
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/finance-entity-field-with-create.tsx.ejs +130 -465
- package/hedhog/frontend/app/_components/finance-layout.tsx.ejs +135 -131
- package/hedhog/frontend/app/accounts-payable/installments/page.tsx.ejs +270 -14
- package/hedhog/frontend/app/accounts-receivable/collections-default/page.tsx.ejs +175 -4
- package/hedhog/frontend/app/accounts-receivable/installments/page.tsx.ejs +271 -19
- package/hedhog/frontend/app/administration/categories/page.tsx.ejs +97 -11
- package/hedhog/frontend/app/administration/cost-centers/page.tsx.ejs +88 -8
- package/hedhog/frontend/app/administration/period-close/page.tsx.ejs +94 -8
- package/hedhog/frontend/app/cash-and-banks/bank-accounts/page.tsx.ejs +163 -42
- package/hedhog/frontend/app/cash-and-banks/bank-reconciliation/page.tsx.ejs +135 -57
- package/hedhog/frontend/app/cash-and-banks/statements/page.tsx.ejs +202 -49
- package/hedhog/frontend/app/cash-and-banks/transfers/page.tsx.ejs +107 -22
- package/hedhog/frontend/messages/en.json +174 -221
- package/hedhog/frontend/messages/pt.json +174 -221
- package/package.json +4 -4
- package/hedhog/frontend/app/_components/person-field-with-create.tsx.ejs +0 -734
|
@@ -36,6 +36,8 @@ import {
|
|
|
36
36
|
SheetHeader,
|
|
37
37
|
SheetTitle,
|
|
38
38
|
} from '@/components/ui/sheet';
|
|
39
|
+
import { useFormDraft } from '@/hooks/use-form-draft';
|
|
40
|
+
import { formatDateTime } from '@/lib/format-date';
|
|
39
41
|
import {
|
|
40
42
|
DndContext,
|
|
41
43
|
DragEndEvent,
|
|
@@ -52,6 +54,8 @@ import {
|
|
|
52
54
|
} from '@dnd-kit/sortable';
|
|
53
55
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
54
56
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
57
|
+
import { formatDistanceToNow } from 'date-fns';
|
|
58
|
+
import { enUS, ptBR } from 'date-fns/locale';
|
|
55
59
|
import {
|
|
56
60
|
ChevronDown,
|
|
57
61
|
ChevronRight,
|
|
@@ -63,7 +67,7 @@ import {
|
|
|
63
67
|
} from 'lucide-react';
|
|
64
68
|
import { useTranslations } from 'next-intl';
|
|
65
69
|
import { useEffect, useMemo, useState } from 'react';
|
|
66
|
-
import { useForm } from 'react-hook-form';
|
|
70
|
+
import { useForm, useWatch } from 'react-hook-form';
|
|
67
71
|
import { z } from 'zod';
|
|
68
72
|
|
|
69
73
|
type CategoryFormValues = {
|
|
@@ -84,6 +88,14 @@ type FinanceCategory = {
|
|
|
84
88
|
|
|
85
89
|
const EMPTY_CATEGORIES: FinanceCategory[] = [];
|
|
86
90
|
|
|
91
|
+
type CategoryDraftPayload = {
|
|
92
|
+
mode: 'create' | 'edit';
|
|
93
|
+
categoryId: string | null;
|
|
94
|
+
values: CategoryFormValues;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const CATEGORY_FORM_DRAFT_STORAGE_KEY = 'finance-categories-form-draft';
|
|
98
|
+
|
|
87
99
|
type CategoryNode = FinanceCategory & { children: CategoryNode[] };
|
|
88
100
|
|
|
89
101
|
function buildTree(categories: FinanceCategory[]): CategoryNode[] {
|
|
@@ -135,7 +147,8 @@ function CategoriaSheet({
|
|
|
135
147
|
categories: FinanceCategory[];
|
|
136
148
|
t: ReturnType<typeof useTranslations>;
|
|
137
149
|
}) {
|
|
138
|
-
const { request, showToastHandler } =
|
|
150
|
+
const { request, showToastHandler, currentLocaleCode, getSettingValue } =
|
|
151
|
+
useApp();
|
|
139
152
|
|
|
140
153
|
const categorySchema = z.object({
|
|
141
154
|
nome: z.string().trim().min(1, t('sheet.validation.nameRequired')),
|
|
@@ -152,30 +165,96 @@ function CategoriaSheet({
|
|
|
152
165
|
},
|
|
153
166
|
});
|
|
154
167
|
|
|
168
|
+
const watchedValues = useWatch({
|
|
169
|
+
control: form.control,
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const {
|
|
173
|
+
clearDraft,
|
|
174
|
+
loadDraft,
|
|
175
|
+
hasDraft,
|
|
176
|
+
savedAt: draftSavedAt,
|
|
177
|
+
} = useFormDraft<CategoryDraftPayload>({
|
|
178
|
+
storageKey: CATEGORY_FORM_DRAFT_STORAGE_KEY,
|
|
179
|
+
value: {
|
|
180
|
+
mode: editing ? 'edit' : 'create',
|
|
181
|
+
categoryId: editing?.id ?? null,
|
|
182
|
+
values: {
|
|
183
|
+
nome: watchedValues.nome ?? '',
|
|
184
|
+
natureza: watchedValues.natureza ?? 'despesa',
|
|
185
|
+
parentId: watchedValues.parentId ?? 'root',
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
hasData: Boolean(
|
|
189
|
+
(watchedValues.nome ?? '').trim() ||
|
|
190
|
+
(watchedValues.natureza ?? 'despesa') !== 'despesa' ||
|
|
191
|
+
(watchedValues.parentId ?? 'root') !== 'root'
|
|
192
|
+
),
|
|
193
|
+
enabled: open,
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const draftStatusContent = useMemo(() => {
|
|
197
|
+
if (!hasDraft || !draftSavedAt) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const savedDate = new Date(draftSavedAt);
|
|
202
|
+
if (Number.isNaN(savedDate.getTime())) {
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const locale = currentLocaleCode.startsWith('pt') ? ptBR : enUS;
|
|
207
|
+
const relativeLabel = formatDistanceToNow(savedDate, {
|
|
208
|
+
addSuffix: true,
|
|
209
|
+
locale,
|
|
210
|
+
});
|
|
211
|
+
const absoluteLabel = formatDateTime(
|
|
212
|
+
savedDate,
|
|
213
|
+
getSettingValue,
|
|
214
|
+
currentLocaleCode
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
return currentLocaleCode.startsWith('pt')
|
|
218
|
+
? `Rascunho salvo ${relativeLabel} • Último salvamento: ${absoluteLabel}`
|
|
219
|
+
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
220
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
221
|
+
|
|
155
222
|
useEffect(() => {
|
|
156
223
|
if (!open) {
|
|
157
|
-
form.reset({ nome: '', natureza: 'despesa', parentId: 'root' });
|
|
158
224
|
return;
|
|
159
225
|
}
|
|
160
226
|
|
|
227
|
+
const storedDraft = loadDraft();
|
|
228
|
+
const shouldRestoreEditDraft =
|
|
229
|
+
Boolean(editing) &&
|
|
230
|
+
storedDraft?.payload.mode === 'edit' &&
|
|
231
|
+
storedDraft.payload.categoryId === editing?.id;
|
|
232
|
+
|
|
161
233
|
if (editing) {
|
|
162
|
-
form.reset(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
234
|
+
form.reset(
|
|
235
|
+
shouldRestoreEditDraft
|
|
236
|
+
? storedDraft.payload.values
|
|
237
|
+
: {
|
|
238
|
+
nome: editing.nome,
|
|
239
|
+
natureza: editing.natureza,
|
|
240
|
+
parentId: editing.parentId || 'root',
|
|
241
|
+
}
|
|
242
|
+
);
|
|
167
243
|
return;
|
|
168
244
|
}
|
|
169
245
|
|
|
170
|
-
form.reset(
|
|
171
|
-
|
|
246
|
+
form.reset(
|
|
247
|
+
storedDraft?.payload.mode === 'create'
|
|
248
|
+
? storedDraft.payload.values
|
|
249
|
+
: { nome: '', natureza: 'despesa', parentId: 'root' }
|
|
250
|
+
);
|
|
251
|
+
}, [open, editing, form, loadDraft]);
|
|
172
252
|
|
|
173
253
|
const handleOpenChange = (nextOpen: boolean) => {
|
|
174
254
|
onOpenChange(nextOpen);
|
|
175
255
|
|
|
176
256
|
if (!nextOpen) {
|
|
177
257
|
setEditing(null);
|
|
178
|
-
form.reset({ nome: '', natureza: 'despesa', parentId: 'root' });
|
|
179
258
|
}
|
|
180
259
|
};
|
|
181
260
|
|
|
@@ -205,6 +284,7 @@ function CategoriaSheet({
|
|
|
205
284
|
});
|
|
206
285
|
}
|
|
207
286
|
|
|
287
|
+
clearDraft();
|
|
208
288
|
await onSaved();
|
|
209
289
|
onOpenChange(false);
|
|
210
290
|
setEditing(null);
|
|
@@ -318,6 +398,12 @@ function CategoriaSheet({
|
|
|
318
398
|
)}
|
|
319
399
|
/>
|
|
320
400
|
|
|
401
|
+
{draftStatusContent ? (
|
|
402
|
+
<p className="text-xs text-muted-foreground">
|
|
403
|
+
{draftStatusContent}
|
|
404
|
+
</p>
|
|
405
|
+
) : null}
|
|
406
|
+
|
|
321
407
|
<div className="flex justify-end gap-2">
|
|
322
408
|
<Button
|
|
323
409
|
type="button"
|
|
@@ -29,12 +29,16 @@ import {
|
|
|
29
29
|
SheetHeader,
|
|
30
30
|
SheetTitle,
|
|
31
31
|
} from '@/components/ui/sheet';
|
|
32
|
+
import { useFormDraft } from '@/hooks/use-form-draft';
|
|
33
|
+
import { formatDateTime } from '@/lib/format-date';
|
|
32
34
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
33
35
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
36
|
+
import { formatDistanceToNow } from 'date-fns';
|
|
37
|
+
import { enUS, ptBR } from 'date-fns/locale';
|
|
34
38
|
import { Building2, Pencil, Plus, Trash2 } from 'lucide-react';
|
|
35
39
|
import { useTranslations } from 'next-intl';
|
|
36
|
-
import { useEffect, useState } from 'react';
|
|
37
|
-
import { useForm } from 'react-hook-form';
|
|
40
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
41
|
+
import { useForm, useWatch } from 'react-hook-form';
|
|
38
42
|
import { z } from 'zod';
|
|
39
43
|
|
|
40
44
|
type CostCenterFormValues = {
|
|
@@ -49,6 +53,14 @@ type CostCenter = {
|
|
|
49
53
|
ativo: boolean;
|
|
50
54
|
};
|
|
51
55
|
|
|
56
|
+
type CostCenterDraftPayload = {
|
|
57
|
+
mode: 'create' | 'edit';
|
|
58
|
+
costCenterId: string | null;
|
|
59
|
+
values: CostCenterFormValues;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const COST_CENTER_FORM_DRAFT_STORAGE_KEY = 'finance-cost-centers-form-draft';
|
|
63
|
+
|
|
52
64
|
function CentroCustoSheet({
|
|
53
65
|
open,
|
|
54
66
|
onOpenChange,
|
|
@@ -64,7 +76,8 @@ function CentroCustoSheet({
|
|
|
64
76
|
onEditingChange: (costCenter: CostCenter | null) => void;
|
|
65
77
|
t: ReturnType<typeof useTranslations>;
|
|
66
78
|
}) {
|
|
67
|
-
const { request, showToastHandler } =
|
|
79
|
+
const { request, showToastHandler, currentLocaleCode, getSettingValue } =
|
|
80
|
+
useApp();
|
|
68
81
|
|
|
69
82
|
const costCenterFormSchema = z.object({
|
|
70
83
|
nome: z.string().trim().min(1, t('sheet.validation.nameRequired')),
|
|
@@ -77,19 +90,80 @@ function CentroCustoSheet({
|
|
|
77
90
|
},
|
|
78
91
|
});
|
|
79
92
|
|
|
93
|
+
const watchedValues = useWatch({
|
|
94
|
+
control: form.control,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const {
|
|
98
|
+
clearDraft,
|
|
99
|
+
loadDraft,
|
|
100
|
+
hasDraft,
|
|
101
|
+
savedAt: draftSavedAt,
|
|
102
|
+
} = useFormDraft<CostCenterDraftPayload>({
|
|
103
|
+
storageKey: COST_CENTER_FORM_DRAFT_STORAGE_KEY,
|
|
104
|
+
value: {
|
|
105
|
+
mode: editingCostCenter ? 'edit' : 'create',
|
|
106
|
+
costCenterId: editingCostCenter?.id ?? null,
|
|
107
|
+
values: {
|
|
108
|
+
nome: watchedValues.nome ?? '',
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
hasData: Boolean((watchedValues.nome ?? '').trim()),
|
|
112
|
+
enabled: open,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const draftStatusContent = useMemo(() => {
|
|
116
|
+
if (!hasDraft || !draftSavedAt) {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const savedDate = new Date(draftSavedAt);
|
|
121
|
+
if (Number.isNaN(savedDate.getTime())) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const locale = currentLocaleCode.startsWith('pt') ? ptBR : enUS;
|
|
126
|
+
const relativeLabel = formatDistanceToNow(savedDate, {
|
|
127
|
+
addSuffix: true,
|
|
128
|
+
locale,
|
|
129
|
+
});
|
|
130
|
+
const absoluteLabel = formatDateTime(
|
|
131
|
+
savedDate,
|
|
132
|
+
getSettingValue,
|
|
133
|
+
currentLocaleCode
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
return currentLocaleCode.startsWith('pt')
|
|
137
|
+
? `Rascunho salvo ${relativeLabel} • Último salvamento: ${absoluteLabel}`
|
|
138
|
+
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
139
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
140
|
+
|
|
80
141
|
useEffect(() => {
|
|
81
142
|
if (!open) {
|
|
82
|
-
form.reset({ nome: '' });
|
|
83
143
|
return;
|
|
84
144
|
}
|
|
85
145
|
|
|
146
|
+
const storedDraft = loadDraft();
|
|
147
|
+
const shouldRestoreEditDraft =
|
|
148
|
+
Boolean(editingCostCenter) &&
|
|
149
|
+
storedDraft?.payload.mode === 'edit' &&
|
|
150
|
+
storedDraft.payload.costCenterId === editingCostCenter?.id;
|
|
151
|
+
|
|
86
152
|
if (editingCostCenter) {
|
|
87
|
-
form.reset(
|
|
153
|
+
form.reset(
|
|
154
|
+
shouldRestoreEditDraft
|
|
155
|
+
? storedDraft.payload.values
|
|
156
|
+
: { nome: editingCostCenter.nome }
|
|
157
|
+
);
|
|
88
158
|
return;
|
|
89
159
|
}
|
|
90
160
|
|
|
91
|
-
form.reset(
|
|
92
|
-
|
|
161
|
+
form.reset(
|
|
162
|
+
storedDraft?.payload.mode === 'create'
|
|
163
|
+
? storedDraft.payload.values
|
|
164
|
+
: { nome: '' }
|
|
165
|
+
);
|
|
166
|
+
}, [open, editingCostCenter, form, loadDraft]);
|
|
93
167
|
|
|
94
168
|
const handleSubmit = async (values: CostCenterFormValues) => {
|
|
95
169
|
try {
|
|
@@ -111,6 +185,7 @@ function CentroCustoSheet({
|
|
|
111
185
|
});
|
|
112
186
|
}
|
|
113
187
|
|
|
188
|
+
clearDraft();
|
|
114
189
|
await onSaved();
|
|
115
190
|
form.reset({ nome: '' });
|
|
116
191
|
onEditingChange(null);
|
|
@@ -135,7 +210,6 @@ function CentroCustoSheet({
|
|
|
135
210
|
onOpenChange(nextOpen);
|
|
136
211
|
|
|
137
212
|
if (!nextOpen) {
|
|
138
|
-
form.reset({ nome: '' });
|
|
139
213
|
onEditingChange(null);
|
|
140
214
|
}
|
|
141
215
|
};
|
|
@@ -176,6 +250,12 @@ function CentroCustoSheet({
|
|
|
176
250
|
)}
|
|
177
251
|
/>
|
|
178
252
|
|
|
253
|
+
{draftStatusContent ? (
|
|
254
|
+
<p className="text-xs text-muted-foreground">
|
|
255
|
+
{draftStatusContent}
|
|
256
|
+
</p>
|
|
257
|
+
) : null}
|
|
258
|
+
|
|
179
259
|
<div className="flex justify-end gap-2">
|
|
180
260
|
<Button
|
|
181
261
|
type="button"
|
|
@@ -34,12 +34,16 @@ import {
|
|
|
34
34
|
TableHeader,
|
|
35
35
|
TableRow,
|
|
36
36
|
} from '@/components/ui/table';
|
|
37
|
+
import { useFormDraft } from '@/hooks/use-form-draft';
|
|
38
|
+
import { formatDateTime } from '@/lib/format-date';
|
|
37
39
|
import { useApp, useQuery } from '@hed-hog/next-app-provider';
|
|
38
40
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
41
|
+
import { formatDistanceToNow } from 'date-fns';
|
|
42
|
+
import { enUS, ptBR } from 'date-fns/locale';
|
|
39
43
|
import { Plus, Search, X } from 'lucide-react';
|
|
40
44
|
import { useTranslations } from 'next-intl';
|
|
41
|
-
import { useState } from 'react';
|
|
42
|
-
import { useForm } from 'react-hook-form';
|
|
45
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
46
|
+
import { useForm, useWatch } from 'react-hook-form';
|
|
43
47
|
import { z } from 'zod';
|
|
44
48
|
|
|
45
49
|
type PeriodClose = {
|
|
@@ -70,6 +74,12 @@ type ClosePeriodFormValues = {
|
|
|
70
74
|
status: 'closed' | 'open';
|
|
71
75
|
};
|
|
72
76
|
|
|
77
|
+
type ClosePeriodDraftPayload = {
|
|
78
|
+
values: ClosePeriodFormValues;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const PERIOD_CLOSE_FORM_DRAFT_STORAGE_KEY = 'finance-period-close-form-draft';
|
|
82
|
+
|
|
73
83
|
function ClosePeriodSheet({
|
|
74
84
|
open,
|
|
75
85
|
onOpenChange,
|
|
@@ -81,7 +91,8 @@ function ClosePeriodSheet({
|
|
|
81
91
|
onCreated: () => Promise<unknown> | void;
|
|
82
92
|
t: ReturnType<typeof useTranslations>;
|
|
83
93
|
}) {
|
|
84
|
-
const { request, showToastHandler } =
|
|
94
|
+
const { request, showToastHandler, currentLocaleCode, getSettingValue } =
|
|
95
|
+
useApp();
|
|
85
96
|
|
|
86
97
|
const closePeriodSchema = z.object({
|
|
87
98
|
periodStart: z.string().min(1, t('sheet.validation.startRequired')),
|
|
@@ -100,6 +111,77 @@ function ClosePeriodSheet({
|
|
|
100
111
|
},
|
|
101
112
|
});
|
|
102
113
|
|
|
114
|
+
const watchedValues = useWatch({
|
|
115
|
+
control: form.control,
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const {
|
|
119
|
+
clearDraft,
|
|
120
|
+
loadDraft,
|
|
121
|
+
hasDraft,
|
|
122
|
+
savedAt: draftSavedAt,
|
|
123
|
+
} = useFormDraft<ClosePeriodDraftPayload>({
|
|
124
|
+
storageKey: PERIOD_CLOSE_FORM_DRAFT_STORAGE_KEY,
|
|
125
|
+
value: {
|
|
126
|
+
values: {
|
|
127
|
+
periodStart: watchedValues.periodStart ?? '',
|
|
128
|
+
periodEnd: watchedValues.periodEnd ?? '',
|
|
129
|
+
notes: watchedValues.notes ?? '',
|
|
130
|
+
status: watchedValues.status ?? 'closed',
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
hasData: Boolean(
|
|
134
|
+
(watchedValues.periodStart ?? '').trim() ||
|
|
135
|
+
(watchedValues.periodEnd ?? '').trim() ||
|
|
136
|
+
(watchedValues.notes ?? '').trim() ||
|
|
137
|
+
(watchedValues.status ?? 'closed') !== 'closed'
|
|
138
|
+
),
|
|
139
|
+
enabled: open,
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
const draftStatusContent = useMemo(() => {
|
|
143
|
+
if (!hasDraft || !draftSavedAt) {
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const savedDate = new Date(draftSavedAt);
|
|
148
|
+
if (Number.isNaN(savedDate.getTime())) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const locale = currentLocaleCode.startsWith('pt') ? ptBR : enUS;
|
|
153
|
+
const relativeLabel = formatDistanceToNow(savedDate, {
|
|
154
|
+
addSuffix: true,
|
|
155
|
+
locale,
|
|
156
|
+
});
|
|
157
|
+
const absoluteLabel = formatDateTime(
|
|
158
|
+
savedDate,
|
|
159
|
+
getSettingValue,
|
|
160
|
+
currentLocaleCode
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
return currentLocaleCode.startsWith('pt')
|
|
164
|
+
? `Rascunho salvo ${relativeLabel} • Último salvamento: ${absoluteLabel}`
|
|
165
|
+
: `Draft saved ${relativeLabel} • Last saved: ${absoluteLabel}`;
|
|
166
|
+
}, [draftSavedAt, currentLocaleCode, getSettingValue, hasDraft]);
|
|
167
|
+
|
|
168
|
+
useEffect(() => {
|
|
169
|
+
if (!open) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const storedDraft = loadDraft();
|
|
174
|
+
|
|
175
|
+
form.reset(
|
|
176
|
+
storedDraft?.payload.values ?? {
|
|
177
|
+
periodStart: '',
|
|
178
|
+
periodEnd: '',
|
|
179
|
+
notes: '',
|
|
180
|
+
status: 'closed',
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
}, [form, loadDraft, open]);
|
|
184
|
+
|
|
103
185
|
const onSubmit = async (values: ClosePeriodFormValues) => {
|
|
104
186
|
try {
|
|
105
187
|
await request({
|
|
@@ -113,6 +195,7 @@ function ClosePeriodSheet({
|
|
|
113
195
|
},
|
|
114
196
|
});
|
|
115
197
|
|
|
198
|
+
clearDraft();
|
|
116
199
|
await onCreated();
|
|
117
200
|
form.reset();
|
|
118
201
|
onOpenChange(false);
|
|
@@ -127,9 +210,6 @@ function ClosePeriodSheet({
|
|
|
127
210
|
open={open}
|
|
128
211
|
onOpenChange={(nextOpen) => {
|
|
129
212
|
onOpenChange(nextOpen);
|
|
130
|
-
if (!nextOpen) {
|
|
131
|
-
form.reset();
|
|
132
|
-
}
|
|
133
213
|
}}
|
|
134
214
|
>
|
|
135
215
|
<SheetContent className="w-full sm:max-w-lg">
|
|
@@ -215,6 +295,12 @@ function ClosePeriodSheet({
|
|
|
215
295
|
)}
|
|
216
296
|
/>
|
|
217
297
|
|
|
298
|
+
{draftStatusContent ? (
|
|
299
|
+
<p className="text-xs text-muted-foreground">
|
|
300
|
+
{draftStatusContent}
|
|
301
|
+
</p>
|
|
302
|
+
) : null}
|
|
303
|
+
|
|
218
304
|
<div className="flex justify-end gap-2">
|
|
219
305
|
<Button
|
|
220
306
|
type="button"
|
|
@@ -311,7 +397,7 @@ export default function PeriodClosePage() {
|
|
|
311
397
|
/>
|
|
312
398
|
|
|
313
399
|
<div className="flex flex-col gap-4 xl:flex-row xl:flex-wrap xl:items-center">
|
|
314
|
-
<div className="relative min-w-
|
|
400
|
+
<div className="relative min-w-65 flex-1">
|
|
315
401
|
<Search className="pointer-events-none absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
|
|
316
402
|
<Input
|
|
317
403
|
placeholder={t('filters.searchPlaceholder')}
|
|
@@ -331,7 +417,7 @@ export default function PeriodClosePage() {
|
|
|
331
417
|
setPage(1);
|
|
332
418
|
}}
|
|
333
419
|
>
|
|
334
|
-
<SelectTrigger className="w-full sm:w-
|
|
420
|
+
<SelectTrigger className="w-full sm:w-45">
|
|
335
421
|
<SelectValue placeholder={t('filters.status')} />
|
|
336
422
|
</SelectTrigger>
|
|
337
423
|
<SelectContent>
|