@accounter/client 0.0.8-alpha-20251028124234-328844c99a42b68aa9e2f32fd86da80b4832f631 → 0.0.8-alpha-20251028124537-8b0946b10a6e597c997017c33fb80fbf674e2feb
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/CHANGELOG.md +84 -13
- package/dist/assets/{Checkbox-BR6kGuhg.js → Checkbox-DBiOK2wr.js} +3 -3
- package/dist/assets/{Progress-7xtiFwK3.js → Progress-3b9RPwUr.js} +1 -1
- package/dist/assets/Typography-BjOvYDtJ.js +1 -0
- package/dist/assets/accordion-gDGB9JKa.js +1 -0
- package/dist/assets/accountant-approvals-aQMSAP78.js +1 -0
- package/dist/assets/all-charges-X9R8PfNk.js +1 -0
- package/dist/assets/{arrow-up-down-DPG1l9S1.js → arrow-up-down-B3nz1j1G.js} +2 -2
- package/dist/assets/{building-2-BgvPBt2Z.js → building-2-DyCA1u9z.js} +2 -2
- package/dist/assets/business-BOAeYn9N.js +27 -0
- package/dist/assets/{business-header-u2sfE_d8.js → business-header-Ck0v04Iw.js} +1 -1
- package/dist/assets/business-transactions-single-_OIHJEfY.js +1 -0
- package/dist/assets/business-trip-CYZP6qrZ.js +1 -0
- package/dist/assets/charges-filters-Dc9JkkaM.js +1 -0
- package/dist/assets/charges-ledger-validation-BiBZ2pEf.js +1 -0
- package/dist/assets/{chart-ByngRufj.js → chart-xV-krckX.js} +6 -6
- package/dist/assets/{data-table-pagination-D4OEFmX_.js → data-table-pagination-BtKmZaSS.js} +3 -3
- package/dist/assets/editable-business-trip-BIRxgXHu.js +16 -0
- package/dist/assets/index-2x_26B9B.js +1 -0
- package/dist/assets/index-4yVbIKWS.js +1 -0
- package/dist/assets/index-B-uojS_H.js +1 -0
- package/dist/assets/index-BFRBCjVk.css +1 -0
- package/dist/assets/index-BVffhJ_X.js +2 -0
- package/dist/assets/index-BZFydPbo.js +1 -0
- package/dist/assets/index-BazMRdI3.js +6 -0
- package/dist/assets/index-BsTpXlvi.js +891 -0
- package/dist/assets/{index-CLUhAJ3t.js → index-C3BnUF_U.js} +3 -3
- package/dist/assets/index-CD_kl3oZ.js +1 -0
- package/dist/assets/{index-UMFH47hN.js → index-CWM7AEkA.js} +4 -4
- package/dist/assets/index-CaXjK2fb.js +2 -0
- package/dist/assets/index-CbJd62Hp.js +1 -0
- package/dist/assets/index-CdKoH7Cz.js +9 -0
- package/dist/assets/index-Crc98w5p.js +1 -0
- package/dist/assets/index-Cs-QBGd0.js +1 -0
- package/dist/assets/index-D2ada9K2.js +1 -0
- package/dist/assets/index-DAkukoD_.js +1 -0
- package/dist/assets/index-DML4EmHc.js +1 -0
- package/dist/assets/{index-Bsl7tJp_.js → index-DuBbCD-l.js} +22 -22
- package/dist/assets/{index-BetG0HVN.js → index-DypFylYK.js} +3 -3
- package/dist/assets/{index-vChLJwSt.js → index-KFd7K_WR.js} +3 -3
- package/dist/assets/index-rwlm4BcW.js +1 -0
- package/dist/assets/index-xA-DiOzv.js +1 -0
- package/dist/assets/{index.es-NphQjU3m.js → index.es-C6nk1zNp.js} +1 -1
- package/dist/assets/issue-document-BezTjH4r.js +1 -0
- package/dist/assets/login-page-I-7tCrbB.js +1 -0
- package/dist/assets/missing-info-charges-BDgEJ4mj.js +1 -0
- package/dist/assets/page-not-found-CIT5vwb-.js +1 -0
- package/dist/assets/{pencil-tV0FsM6V.js → pencil-BHXyXIP9.js} +2 -2
- package/dist/assets/report-commentary-row-DHfnYhMN.js +1 -0
- package/dist/assets/{save-Czmh3tvC.js → save-NUZuyPEH.js} +2 -2
- package/dist/assets/sub-3UcXQDsZ.js +1 -0
- package/dist/assets/subMonths-BbuiFsxa.js +1 -0
- package/dist/index.html +2 -2
- package/package.json +5 -5
- package/src/components/business/admin-business-section.tsx +74 -36
- package/src/components/business/contracts-section.tsx +25 -4
- package/src/components/business-transactions/business-extended-info.tsx +5 -5
- package/src/components/business-transactions/index.tsx +28 -1
- package/src/components/businesses/index.tsx +2 -6
- package/src/components/charges/cells/business-trip.tsx +1 -6
- package/src/components/charges/cells/counterparty.tsx +28 -4
- package/src/components/charges/helpers.ts +15 -0
- package/src/components/clients/contracts/modify-contract-dialog.tsx +70 -14
- package/src/components/clients/modify-client-dialog.tsx +27 -9
- package/src/components/common/business-trip-report/parts/core-expense-row.tsx +2 -2
- package/src/components/common/business-trip-report/parts/report-header.tsx +1 -2
- package/src/components/common/business-trip-report/parts/uncategorized-transactions.tsx +2 -2
- package/src/components/common/buttons/charge-navigate-button.tsx +11 -12
- package/src/components/common/modals/edit-charge-modal.tsx +2 -2
- package/src/components/common/modals/insert-business.tsx +88 -36
- package/src/components/common/modals/insert-document-modal.tsx +2 -2
- package/src/components/common/modals/match-document-modal.tsx +2 -2
- package/src/components/common/new-documents-list.tsx +2 -2
- package/src/components/documents-table/cells/creditor.tsx +11 -2
- package/src/components/documents-table/cells/debtor.tsx +11 -2
- package/src/components/layout/user-nav.tsx +22 -3
- package/src/components/ledger-table/counterparty-cell.tsx +33 -4
- package/src/components/reports/conto/index.tsx +18 -1
- package/src/components/reports/trial-balance-report/index.tsx +17 -1
- package/src/components/screens/businesses/business.tsx +4 -0
- package/src/components/screens/charges/all-charges.tsx +17 -1
- package/src/components/screens/charges/charge.tsx +4 -0
- package/src/components/screens/reports/balance-report/index.tsx +14 -0
- package/src/components/screens/reports/depreciation-report/index.tsx +14 -0
- package/src/components/transactions-table/cells/counterparty.tsx +23 -2
- package/src/components/transactions-table/cells-legacy/counterparty.tsx +26 -3
- package/src/gql/gql.ts +9 -9
- package/src/gql/graphql.ts +29 -23
- package/src/hooks/use-get-all-contracts.ts +1 -1
- package/src/providers/urql.tsx +2 -2
- package/dist/assets/MultiSelect-BqcJrWnD.js +0 -1
- package/dist/assets/Pagination-6Sv5LXxl.js +0 -1
- package/dist/assets/Table-C5zxD95i.js +0 -1
- package/dist/assets/Typography-CMzSQZKD.js +0 -1
- package/dist/assets/YearPickerInput-CllwSjcn.js +0 -1
- package/dist/assets/accordion-CMR2fANH.js +0 -1
- package/dist/assets/accountant-approvals-BHFXpHHc.js +0 -1
- package/dist/assets/accounter-table-CpeQD4PG.js +0 -1
- package/dist/assets/addDays-DvwuJbUs.js +0 -1
- package/dist/assets/all-charges-At7WJXuW.js +0 -1
- package/dist/assets/business-DKvbSnga.js +0 -32
- package/dist/assets/business-extended-info-7CM8px2e.js +0 -13
- package/dist/assets/business-transactions-filters-DmpO9Bwo.js +0 -1
- package/dist/assets/business-transactions-single-rF6JbAL7.js +0 -1
- package/dist/assets/business-trip-BGrp09N7.js +0 -1
- package/dist/assets/charge-C-EaA1Xc.js +0 -1
- package/dist/assets/charges-filters-Dq-8QHH-.js +0 -1
- package/dist/assets/charges-ledger-validation-DlkzVow7.js +0 -1
- package/dist/assets/charges-table-Cncs1HLi.js +0 -62
- package/dist/assets/create-event-handler-BiA-1lGu.js +0 -1
- package/dist/assets/download-csv-button-Df5rDeDc.js +0 -1
- package/dist/assets/editable-business-trip-Bav24z0u.js +0 -16
- package/dist/assets/funnel-BJ71hzoq.js +0 -6
- package/dist/assets/index-BRv0JZw4.js +0 -1
- package/dist/assets/index-BXlS8oD_.js +0 -1
- package/dist/assets/index-BplSRMAq.css +0 -1
- package/dist/assets/index-Cix5qjA-.js +0 -2
- package/dist/assets/index-CizLtiES.js +0 -1
- package/dist/assets/index-DKBzv0gc.js +0 -1
- package/dist/assets/index-DR_5jpS4.js +0 -6
- package/dist/assets/index-DTmtILfq.js +0 -1
- package/dist/assets/index-DU0G7FZm.js +0 -1
- package/dist/assets/index-DUWRgLfu.js +0 -9
- package/dist/assets/index-DYZPWG4k.js +0 -2
- package/dist/assets/index-DdUE2_44.js +0 -1
- package/dist/assets/index-De5dvO0S.js +0 -1
- package/dist/assets/index-Des3eR4f.js +0 -1
- package/dist/assets/index-DpYwi5kf.js +0 -6
- package/dist/assets/index-GzyQZkbY.js +0 -1
- package/dist/assets/index-HzLXi-qB.js +0 -1
- package/dist/assets/index-Ji28AZwq.js +0 -1
- package/dist/assets/index-fuT9duEO.js +0 -1
- package/dist/assets/index-wck8Xuay.js +0 -1
- package/dist/assets/index-wyU9I4Kz.js +0 -768
- package/dist/assets/insert-business-trip-modal-vS1QrUJz.js +0 -6
- package/dist/assets/issue-document-pIswc_8i.js +0 -1
- package/dist/assets/list-plus-Dy3vzJVy.js +0 -6
- package/dist/assets/login-page-YXRfklK1.js +0 -1
- package/dist/assets/match-document-modal-BPG_hljb.js +0 -16
- package/dist/assets/missing-info-charges-D8dUfChs.js +0 -1
- package/dist/assets/modal-D47umnak.js +0 -1
- package/dist/assets/page-layout-BG0XvWfD.js +0 -1
- package/dist/assets/page-not-found-Cy6oIIb1.js +0 -1
- package/dist/assets/panel-top-open-B1rhJYjQ.js +0 -11
- package/dist/assets/report-commentary-row-BL2RkIHq.js +0 -1
- package/dist/assets/similar-transactions-modal-MQeC2gtu.js +0 -1
- package/dist/assets/sub-B4_VmmF9.js +0 -1
- package/dist/assets/subMonths-DG7w6bCY.js +0 -1
- package/dist/assets/summary-DvHtnArZ.js +0 -1
- package/dist/assets/switch-GSloW_Ey.js +0 -1
- package/dist/assets/toggle-expansion-button-lwJYTklN.js +0 -1
- package/dist/assets/tooltip-BbKSwLCX.js +0 -1
- package/dist/assets/use-url-query-CUVSXgm0.js +0 -1
|
@@ -49,9 +49,10 @@ interface Props {
|
|
|
49
49
|
businessId: string;
|
|
50
50
|
client?: ClientFormValues | null;
|
|
51
51
|
onDone?: () => void;
|
|
52
|
+
showTrigger?: boolean;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
export function ModifyClientDialog({ client, businessId, onDone }: Props) {
|
|
55
|
+
export function ModifyClientDialog({ client, businessId, onDone, showTrigger = true }: Props) {
|
|
55
56
|
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
|
56
57
|
const [editingClient, setEditingClient] = useState<ClientFormValues | null>(null);
|
|
57
58
|
|
|
@@ -138,13 +139,23 @@ export function ModifyClientDialog({ client, businessId, onDone }: Props) {
|
|
|
138
139
|
);
|
|
139
140
|
|
|
140
141
|
return (
|
|
141
|
-
<Dialog
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
142
|
+
<Dialog
|
|
143
|
+
open={isDialogOpen}
|
|
144
|
+
onOpenChange={status => {
|
|
145
|
+
setIsDialogOpen(status);
|
|
146
|
+
if (!status) {
|
|
147
|
+
onDone?.();
|
|
148
|
+
}
|
|
149
|
+
}}
|
|
150
|
+
>
|
|
151
|
+
{showTrigger && (
|
|
152
|
+
<DialogTrigger asChild>
|
|
153
|
+
<Button size="sm" onClick={handleNew}>
|
|
154
|
+
<Plus className="h-4 w-4 mr-2" />
|
|
155
|
+
New Client
|
|
156
|
+
</Button>
|
|
157
|
+
</DialogTrigger>
|
|
158
|
+
)}
|
|
148
159
|
<DialogContent className="max-w-2xl max-h-[90vh] overflow-y-auto">
|
|
149
160
|
<DialogHeader>
|
|
150
161
|
<DialogTitle>{editingClient ? 'Edit Client' : 'Create New Client'}</DialogTitle>
|
|
@@ -263,7 +274,14 @@ export function ModifyClientDialog({ client, businessId, onDone }: Props) {
|
|
|
263
274
|
</div>
|
|
264
275
|
</div>
|
|
265
276
|
<DialogFooter>
|
|
266
|
-
<Button
|
|
277
|
+
<Button
|
|
278
|
+
type="button"
|
|
279
|
+
variant="outline"
|
|
280
|
+
onClick={() => {
|
|
281
|
+
setIsDialogOpen(false);
|
|
282
|
+
onDone?.();
|
|
283
|
+
}}
|
|
284
|
+
>
|
|
267
285
|
Cancel
|
|
268
286
|
</Button>
|
|
269
287
|
<Button type="submit">{editingClient ? 'Update Client' : 'Create Client'}</Button>
|
|
@@ -4,7 +4,6 @@ import { Controller, type Control } from 'react-hook-form';
|
|
|
4
4
|
import { Link } from 'react-router-dom';
|
|
5
5
|
import { toast } from 'sonner';
|
|
6
6
|
import { useQuery } from 'urql';
|
|
7
|
-
import { ROUTES } from '@/router/routes.js';
|
|
8
7
|
import { Select, Text } from '@mantine/core';
|
|
9
8
|
import { DatePickerInput } from '@mantine/dates';
|
|
10
9
|
import {
|
|
@@ -15,6 +14,7 @@ import {
|
|
|
15
14
|
} from '../../../../gql/graphql.js';
|
|
16
15
|
import { getFragmentData, type FragmentType } from '../../../../gql/index.js';
|
|
17
16
|
import { TIMELESS_DATE_REGEX } from '../../../../helpers/consts.js';
|
|
17
|
+
import { getChargeHref } from '../../../screens/charges/charge.js';
|
|
18
18
|
import { CurrencyInput } from '../../index.js';
|
|
19
19
|
|
|
20
20
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
@@ -239,7 +239,7 @@ export const CoreExpenseRow = ({
|
|
|
239
239
|
{linkedChargeIds.map(id => (
|
|
240
240
|
<Link
|
|
241
241
|
key={id}
|
|
242
|
-
to={
|
|
242
|
+
to={getChargeHref(id)}
|
|
243
243
|
target="_blank"
|
|
244
244
|
rel="noreferrer"
|
|
245
245
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { differenceInDays, format, setHours } from 'date-fns';
|
|
3
|
-
import { ROUTES } from '@/router/routes.js';
|
|
4
3
|
import { Grid, Text } from '@mantine/core';
|
|
5
4
|
import { BusinessTripReportHeaderFieldsFragmentDoc } from '../../../../gql/graphql.js';
|
|
6
5
|
import { getFragmentData, type FragmentType } from '../../../../gql/index.js';
|
|
@@ -44,7 +43,7 @@ export const ReportHeader = ({ data, onChange }: Props): ReactElement => {
|
|
|
44
43
|
<AccountantApproval data={businessTrip} onChange={onChange} />
|
|
45
44
|
<CopyToClipboardButton
|
|
46
45
|
isLink
|
|
47
|
-
content={`${window.location.origin}
|
|
46
|
+
content={`${window.location.origin}/business-trips/${businessTrip.id}`}
|
|
48
47
|
/>
|
|
49
48
|
<BusinessTripToggleMenu businessTripId={businessTrip.id} />
|
|
50
49
|
</div>
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { AlertCircle } from 'lucide-react';
|
|
3
3
|
import { Link } from 'react-router-dom';
|
|
4
|
-
import { ROUTES } from '@/router/routes.js';
|
|
5
4
|
import { Popover, Table, Text } from '@mantine/core';
|
|
6
5
|
import { useDisclosure } from '@mantine/hooks';
|
|
7
6
|
import {
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
} from '../../../../gql/graphql.js';
|
|
12
11
|
import { getFragmentData, type FragmentType } from '../../../../gql/index.js';
|
|
13
12
|
import { formatStringifyAmount } from '../../../../helpers/index.js';
|
|
13
|
+
import { getChargeHref } from '../../../screens/charges/charge.js';
|
|
14
14
|
import {
|
|
15
15
|
Account,
|
|
16
16
|
Counterparty,
|
|
@@ -94,7 +94,7 @@ export const UncategorizedTransactions = ({ data, onChange }: Props): ReactEleme
|
|
|
94
94
|
<Amount data={uncategorizedTransaction} />
|
|
95
95
|
<td>
|
|
96
96
|
<Link
|
|
97
|
-
to={
|
|
97
|
+
to={getChargeHref(uncategorizedTransaction.transaction.chargeId)}
|
|
98
98
|
target="_blank"
|
|
99
99
|
rel="noreferrer"
|
|
100
100
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { ComponentProps, ReactElement } from 'react';
|
|
2
2
|
import { ExternalLink } from 'lucide-react';
|
|
3
|
-
import { Link } from 'react-router-dom';
|
|
4
3
|
import { Tooltip } from '@mantine/core';
|
|
5
4
|
import { cn } from '../../../lib/utils.js';
|
|
6
|
-
import {
|
|
5
|
+
import { getChargeHref } from '../../screens/charges/charge.js';
|
|
7
6
|
import { Button } from '../../ui/button.js';
|
|
8
7
|
|
|
9
8
|
export function ChargeNavigateButton(
|
|
@@ -11,17 +10,17 @@ export function ChargeNavigateButton(
|
|
|
11
10
|
): ReactElement {
|
|
12
11
|
return (
|
|
13
12
|
<Tooltip label="To Charge">
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
<Button
|
|
14
|
+
onClick={event => {
|
|
15
|
+
event.stopPropagation();
|
|
16
|
+
window.open(getChargeHref(props.chargeId), '_blank', 'noreferrer');
|
|
17
|
+
}}
|
|
18
|
+
{...props}
|
|
19
|
+
className={cn('size-7.5', props.className)}
|
|
20
|
+
variant="ghost"
|
|
20
21
|
>
|
|
21
|
-
<
|
|
22
|
-
|
|
23
|
-
</Button>
|
|
24
|
-
</Link>
|
|
22
|
+
<ExternalLink className="size-5" />
|
|
23
|
+
</Button>
|
|
25
24
|
</Tooltip>
|
|
26
25
|
);
|
|
27
26
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { useQuery } from 'urql';
|
|
3
|
-
import { ROUTES } from '@/router/routes.js';
|
|
4
3
|
import { Loader } from '@mantine/core';
|
|
5
4
|
import { EditChargeDocument } from '../../../gql/graphql.js';
|
|
5
|
+
import { getChargeHref } from '../../screens/charges/charge.js';
|
|
6
6
|
import { CopyToClipboardButton, EditCharge, PopUpDrawer } from '../index.js';
|
|
7
7
|
|
|
8
8
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
@@ -89,7 +89,7 @@ export const EditChargeModalContent = ({
|
|
|
89
89
|
ID: {chargeId}
|
|
90
90
|
<CopyToClipboardButton
|
|
91
91
|
isLink
|
|
92
|
-
content={`${window.location.origin}${
|
|
92
|
+
content={`${window.location.origin}${getChargeHref(chargeId)}`}
|
|
93
93
|
/>
|
|
94
94
|
</div>
|
|
95
95
|
</div>
|
|
@@ -2,6 +2,10 @@ import { useCallback, useContext, useState } from 'react';
|
|
|
2
2
|
import { Globe, Mail, MapPin, Phone, Plus, X } from 'lucide-react';
|
|
3
3
|
import { useForm } from 'react-hook-form';
|
|
4
4
|
import { z } from 'zod';
|
|
5
|
+
import {
|
|
6
|
+
ModifyClientDialog,
|
|
7
|
+
type ClientFormValues,
|
|
8
|
+
} from '@/components/clients/modify-client-dialog.js';
|
|
5
9
|
import { Badge } from '@/components/ui/badge.js';
|
|
6
10
|
import { Button } from '@/components/ui/button.js';
|
|
7
11
|
import {
|
|
@@ -15,6 +19,7 @@ import {
|
|
|
15
19
|
import {
|
|
16
20
|
Form,
|
|
17
21
|
FormControl,
|
|
22
|
+
FormDescription,
|
|
18
23
|
FormField,
|
|
19
24
|
FormItem,
|
|
20
25
|
FormLabel,
|
|
@@ -28,7 +33,9 @@ import {
|
|
|
28
33
|
SelectTrigger,
|
|
29
34
|
SelectValue,
|
|
30
35
|
} from '@/components/ui/select.js';
|
|
36
|
+
import { Switch } from '@/components/ui/switch.js';
|
|
31
37
|
import { Textarea } from '@/components/ui/textarea.js';
|
|
38
|
+
import { DocumentType } from '@/gql/graphql.js';
|
|
32
39
|
import { pcn874RecordEnum } from '@/helpers/index.js';
|
|
33
40
|
import { useAllCountries } from '@/hooks/use-get-countries.js';
|
|
34
41
|
import { useGetSortCodes } from '@/hooks/use-get-sort-codes.js';
|
|
@@ -48,8 +55,8 @@ const businessFormSchema = z
|
|
|
48
55
|
localName: z.string().optional(),
|
|
49
56
|
govId: z.string().optional(),
|
|
50
57
|
address: z.string().optional(),
|
|
51
|
-
generalContacts: z.array(z.
|
|
52
|
-
website: z.
|
|
58
|
+
generalContacts: z.array(z.email()),
|
|
59
|
+
website: z.url().optional().or(z.literal('')),
|
|
53
60
|
phone: z.string().optional(),
|
|
54
61
|
taxCategory: z.string().optional(),
|
|
55
62
|
sortCode: z.string().optional(),
|
|
@@ -57,8 +64,9 @@ const businessFormSchema = z
|
|
|
57
64
|
irsCode: z.int().optional(),
|
|
58
65
|
defaultDescription: z.string().optional(),
|
|
59
66
|
defaultTags: z.array(z.string()),
|
|
67
|
+
isClient: z.boolean().default(false).optional(),
|
|
60
68
|
transactionPhrases: z.array(z.string()),
|
|
61
|
-
emailAddresses: z.array(z.
|
|
69
|
+
emailAddresses: z.array(z.email()),
|
|
62
70
|
})
|
|
63
71
|
.refine(
|
|
64
72
|
data => {
|
|
@@ -117,6 +125,7 @@ export function InsertBusiness({
|
|
|
117
125
|
onAdd?: (businessId: string) => void;
|
|
118
126
|
}) {
|
|
119
127
|
const [isNewBusinessOpen, setIsNewBusinessOpen] = useState(false);
|
|
128
|
+
const [client, setClient] = useState<ClientFormValues | null>(null);
|
|
120
129
|
|
|
121
130
|
const { insertBusiness, fetching: addingInProcess } = useInsertBusiness();
|
|
122
131
|
|
|
@@ -128,6 +137,7 @@ export function InsertBusiness({
|
|
|
128
137
|
defaultTags: [],
|
|
129
138
|
transactionPhrases: description ? [description] : [],
|
|
130
139
|
emailAddresses: [],
|
|
140
|
+
locality: 'GAB', // TODO: set default based on DB
|
|
131
141
|
},
|
|
132
142
|
});
|
|
133
143
|
|
|
@@ -135,44 +145,69 @@ export function InsertBusiness({
|
|
|
135
145
|
const newBusiness = await insertBusiness({
|
|
136
146
|
fields: convertFormDataToInsertNewBusinessInput(data),
|
|
137
147
|
});
|
|
148
|
+
if (data.isClient && newBusiness?.id) {
|
|
149
|
+
setClient({
|
|
150
|
+
businessId: newBusiness.id,
|
|
151
|
+
generatedDocumentType: DocumentType.Proforma,
|
|
152
|
+
emails: [],
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
onComplete(newBusiness?.id);
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const onComplete = (businessId: string = '') => {
|
|
160
|
+
setClient(null);
|
|
138
161
|
setIsNewBusinessOpen(false);
|
|
139
162
|
form.reset();
|
|
140
|
-
onAdd?.(
|
|
163
|
+
onAdd?.(businessId);
|
|
141
164
|
};
|
|
142
165
|
|
|
143
166
|
return (
|
|
144
|
-
|
|
145
|
-
<
|
|
146
|
-
<
|
|
147
|
-
<
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
<
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
<
|
|
158
|
-
<
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
<
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
167
|
+
<>
|
|
168
|
+
<Dialog open={isNewBusinessOpen} onOpenChange={setIsNewBusinessOpen}>
|
|
169
|
+
<DialogTrigger asChild>
|
|
170
|
+
<Button>
|
|
171
|
+
<Plus className="size-4 mr-2" />
|
|
172
|
+
New Business
|
|
173
|
+
</Button>
|
|
174
|
+
</DialogTrigger>
|
|
175
|
+
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto">
|
|
176
|
+
<DialogHeader>
|
|
177
|
+
<DialogTitle>Create New Business</DialogTitle>
|
|
178
|
+
<DialogDescription>Add a new business to Accounter.</DialogDescription>
|
|
179
|
+
</DialogHeader>
|
|
180
|
+
<Form {...form}>
|
|
181
|
+
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
|
|
182
|
+
<ContactInformationSection form={form} />
|
|
183
|
+
|
|
184
|
+
<DefaultsSection form={form} />
|
|
185
|
+
|
|
186
|
+
<AutoMatchingSection form={form} />
|
|
187
|
+
|
|
188
|
+
<div className="flex justify-end gap-3 pt-4 border-t">
|
|
189
|
+
<Button type="button" variant="outline" onClick={() => setIsNewBusinessOpen(false)}>
|
|
190
|
+
Cancel
|
|
191
|
+
</Button>
|
|
192
|
+
<Button type="submit" disabled={addingInProcess}>
|
|
193
|
+
Create Business
|
|
194
|
+
</Button>
|
|
195
|
+
</div>
|
|
196
|
+
</form>
|
|
197
|
+
</Form>
|
|
198
|
+
</DialogContent>
|
|
199
|
+
</Dialog>
|
|
200
|
+
{client?.businessId && (
|
|
201
|
+
<ModifyClientDialog
|
|
202
|
+
businessId={client.businessId}
|
|
203
|
+
client={client}
|
|
204
|
+
showTrigger={false}
|
|
205
|
+
onDone={() => {
|
|
206
|
+
onComplete(client.businessId);
|
|
207
|
+
}}
|
|
208
|
+
/>
|
|
209
|
+
)}
|
|
210
|
+
</>
|
|
176
211
|
);
|
|
177
212
|
}
|
|
178
213
|
|
|
@@ -538,12 +573,29 @@ function DefaultsSection({ form }: SectionProps) {
|
|
|
538
573
|
placeholder="Select Default Tags"
|
|
539
574
|
variant="default"
|
|
540
575
|
disabled={fetchingTags}
|
|
576
|
+
asChild
|
|
541
577
|
/>
|
|
542
578
|
</FormControl>
|
|
543
579
|
<FormMessage />
|
|
544
580
|
</FormItem>
|
|
545
581
|
)}
|
|
546
582
|
/>
|
|
583
|
+
|
|
584
|
+
<FormField
|
|
585
|
+
control={form.control}
|
|
586
|
+
name="isClient"
|
|
587
|
+
render={({ field }) => (
|
|
588
|
+
<FormItem className="flex flex-row items-center justify-between rounded-lg border p-3 shadow-sm">
|
|
589
|
+
<div className="space-y-0.5">
|
|
590
|
+
<FormLabel>Client</FormLabel>
|
|
591
|
+
<FormDescription>Business is a client</FormDescription>
|
|
592
|
+
</div>
|
|
593
|
+
<FormControl>
|
|
594
|
+
<Switch checked={field.value} onCheckedChange={field.onChange} />
|
|
595
|
+
</FormControl>
|
|
596
|
+
</FormItem>
|
|
597
|
+
)}
|
|
598
|
+
/>
|
|
547
599
|
</div>
|
|
548
600
|
</div>
|
|
549
601
|
);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { getChargeHref } from '../../screens/charges/charge.js';
|
|
3
3
|
import { CopyToClipboardButton, InsertDocument, PopUpDrawer } from '../index.js';
|
|
4
4
|
|
|
5
5
|
interface Props {
|
|
@@ -24,7 +24,7 @@ export const InsertDocumentModal = ({
|
|
|
24
24
|
Charge ID: {chargeId}
|
|
25
25
|
<CopyToClipboardButton
|
|
26
26
|
isLink
|
|
27
|
-
content={`${window.location.origin}${
|
|
27
|
+
content={`${window.location.origin}${getChargeHref(chargeId)}`}
|
|
28
28
|
/>
|
|
29
29
|
</div>
|
|
30
30
|
</div>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { getChargeHref } from '../../screens/charges/charge.js';
|
|
3
3
|
import { DocumentsToChargeMatcher } from '../documents-to-charge-matcher/index.js';
|
|
4
4
|
import { CopyToClipboardButton, PopUpDrawer } from '../index.js';
|
|
5
5
|
|
|
@@ -25,7 +25,7 @@ export const MatchDocumentModal = ({
|
|
|
25
25
|
Charge ID: {chargeId}
|
|
26
26
|
<CopyToClipboardButton
|
|
27
27
|
isLink
|
|
28
|
-
content={`${window.location.origin}${
|
|
28
|
+
content={`${window.location.origin}${getChargeHref(chargeId)}`}
|
|
29
29
|
/>
|
|
30
30
|
</div>
|
|
31
31
|
</div>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
-
import { ROUTES } from '@/router/routes.js';
|
|
4
3
|
import { NewFetchedDocumentFieldsFragmentDoc } from '../../gql/graphql.js';
|
|
5
4
|
import { getFragmentData, type FragmentType } from '../../gql/index.js';
|
|
5
|
+
import { getChargeHref } from '../screens/charges/charge.js';
|
|
6
6
|
|
|
7
7
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions -- used by codegen
|
|
8
8
|
/* GraphQL */ `
|
|
@@ -34,7 +34,7 @@ export const NewDocumentsList = ({ data }: Props): ReactElement => {
|
|
|
34
34
|
.map(doc => (
|
|
35
35
|
<Link
|
|
36
36
|
key={doc.id}
|
|
37
|
-
to={
|
|
37
|
+
to={getChargeHref(doc.charge!.id)}
|
|
38
38
|
target="_blank"
|
|
39
39
|
rel="noreferrer"
|
|
40
40
|
onClick={event => event.stopPropagation()}
|
|
@@ -3,8 +3,9 @@ import { Link } from 'react-router-dom';
|
|
|
3
3
|
import { DocumentType } from '@/gql/graphql.js';
|
|
4
4
|
import { useGetBusinesses } from '@/hooks/use-get-businesses.js';
|
|
5
5
|
import { useUpdateDocument } from '@/hooks/use-update-document.js';
|
|
6
|
-
import {
|
|
6
|
+
import { useUrlQuery } from '@/hooks/use-url-query.js';
|
|
7
7
|
import { Indicator } from '@mantine/core';
|
|
8
|
+
import { getBusinessHref } from '../../charges/helpers.js';
|
|
8
9
|
import { ConfirmMiniButton, InsertBusiness, SelectWithSearch } from '../../common/index.js';
|
|
9
10
|
import type { DocumentsTableRowType } from '../columns.js';
|
|
10
11
|
|
|
@@ -19,6 +20,7 @@ type Props = {
|
|
|
19
20
|
};
|
|
20
21
|
|
|
21
22
|
export const Creditor = ({ document, onChange }: Props): ReactElement => {
|
|
23
|
+
const { get } = useUrlQuery();
|
|
22
24
|
const dbCreditor = 'creditor' in document ? document.creditor : undefined;
|
|
23
25
|
|
|
24
26
|
const shouldHaveCreditor =
|
|
@@ -28,6 +30,13 @@ export const Creditor = ({ document, onChange }: Props): ReactElement => {
|
|
|
28
30
|
|
|
29
31
|
const { selectableBusinesses, refresh: refreshBusinesses } = useGetBusinesses();
|
|
30
32
|
|
|
33
|
+
const encodedFilters = get('chargesFilters');
|
|
34
|
+
|
|
35
|
+
const getHref = useCallback(
|
|
36
|
+
(businessId: string) => getBusinessHref(businessId, encodedFilters as string),
|
|
37
|
+
[encodedFilters],
|
|
38
|
+
);
|
|
39
|
+
|
|
31
40
|
const suggestedCreditor = useMemo(() => {
|
|
32
41
|
if (dbCreditor || !('missingInfoSuggestions' in document) || !document.missingInfoSuggestions) {
|
|
33
42
|
// case when creditor is already set or no suggestions
|
|
@@ -97,7 +106,7 @@ export const Creditor = ({ document, onChange }: Props): ReactElement => {
|
|
|
97
106
|
{shouldHaveCreditor &&
|
|
98
107
|
(id ? (
|
|
99
108
|
<Link
|
|
100
|
-
to={
|
|
109
|
+
to={getHref(id)}
|
|
101
110
|
target="_blank"
|
|
102
111
|
rel="noreferrer"
|
|
103
112
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useCallback, useMemo, useState, type ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
3
|
import { useGetBusinesses } from '@/hooks/use-get-businesses.js';
|
|
4
|
-
import { ROUTES } from '@/router/routes.js';
|
|
5
4
|
import { Indicator } from '@mantine/core';
|
|
6
5
|
import { DocumentType } from '../../../gql/graphql.js';
|
|
7
6
|
import { useUpdateDocument } from '../../../hooks/use-update-document.js';
|
|
7
|
+
import { useUrlQuery } from '../../../hooks/use-url-query.js';
|
|
8
|
+
import { getBusinessHref } from '../../charges/helpers.js';
|
|
8
9
|
import { ConfirmMiniButton, InsertBusiness, SelectWithSearch } from '../../common/index.js';
|
|
9
10
|
import type { DocumentsTableRowType } from '../columns.js';
|
|
10
11
|
import { COUNTERPARTIES_LESS_DOCUMENT_TYPES } from './index.js';
|
|
@@ -15,6 +16,7 @@ type Props = {
|
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const Debtor = ({ document, onChange }: Props): ReactElement => {
|
|
19
|
+
const { get } = useUrlQuery();
|
|
18
20
|
const dbDebtor = 'debtor' in document ? document.debtor : undefined;
|
|
19
21
|
|
|
20
22
|
const shouldHaveDebtor =
|
|
@@ -24,6 +26,13 @@ export const Debtor = ({ document, onChange }: Props): ReactElement => {
|
|
|
24
26
|
|
|
25
27
|
const { selectableBusinesses, refresh: refreshBusinesses } = useGetBusinesses();
|
|
26
28
|
|
|
29
|
+
const encodedFilters = get('chargesFilters');
|
|
30
|
+
|
|
31
|
+
const getHref = useCallback(
|
|
32
|
+
(businessId: string) => getBusinessHref(businessId, encodedFilters as string),
|
|
33
|
+
[encodedFilters],
|
|
34
|
+
);
|
|
35
|
+
|
|
27
36
|
const suggestedDebtor = useMemo(() => {
|
|
28
37
|
if (dbDebtor || !('missingInfoSuggestions' in document) || !document.missingInfoSuggestions) {
|
|
29
38
|
// case when creditor is already set or no suggestions
|
|
@@ -93,7 +102,7 @@ export const Debtor = ({ document, onChange }: Props): ReactElement => {
|
|
|
93
102
|
{shouldHaveDebtor &&
|
|
94
103
|
(id ? (
|
|
95
104
|
<Link
|
|
96
|
-
to={
|
|
105
|
+
to={getHref(id)}
|
|
97
106
|
target="_blank"
|
|
98
107
|
rel="noreferrer"
|
|
99
108
|
onClick={event => event.stopPropagation()}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { useState, type JSX } from 'react';
|
|
2
|
-
import { CircleCheckBig, FileDown, User2Icon } from 'lucide-react';
|
|
1
|
+
import { useContext, useState, type JSX } from 'react';
|
|
2
|
+
import { CircleCheckBig, FileDown, Shield, User2Icon } from 'lucide-react';
|
|
3
|
+
import { Link } from 'react-router-dom';
|
|
4
|
+
import { UserContext } from '@/providers/index.js';
|
|
5
|
+
import { ROUTES } from '@/router/routes.js';
|
|
3
6
|
import { Tooltip } from '@mantine/core';
|
|
4
7
|
import { useDisclosure } from '@mantine/hooks';
|
|
5
8
|
import { useCornJobs } from '../../hooks/use-corn-jobs.js';
|
|
@@ -17,11 +20,14 @@ import {
|
|
|
17
20
|
} from '../ui/dropdown-menu.js';
|
|
18
21
|
|
|
19
22
|
export function UserNav(): JSX.Element {
|
|
23
|
+
const { userContext } = useContext(UserContext);
|
|
20
24
|
const [pullDocumentsOpened, { close: closePullDocuments, open: openPullDocuments }] =
|
|
21
25
|
useDisclosure(false);
|
|
22
26
|
const [balanceChargeModalOpen, setBalanceChargeModalOpen] = useState(false);
|
|
23
27
|
const { executeJobs } = useCornJobs();
|
|
24
28
|
|
|
29
|
+
const userName = userContext?.username || 'User Name';
|
|
30
|
+
|
|
25
31
|
return (
|
|
26
32
|
<>
|
|
27
33
|
<DropdownMenu>
|
|
@@ -35,11 +41,24 @@ export function UserNav(): JSX.Element {
|
|
|
35
41
|
<DropdownMenuContent className="w-56" align="end" forceMount>
|
|
36
42
|
<DropdownMenuLabel className="font-normal">
|
|
37
43
|
<div className="flex flex-col space-y-1">
|
|
38
|
-
<p className="text-sm font-medium leading-none">
|
|
44
|
+
<p className="text-sm font-medium leading-none">{userName}</p>
|
|
39
45
|
<p className="text-xs leading-none text-muted-foreground">Email</p>
|
|
40
46
|
</div>
|
|
41
47
|
</DropdownMenuLabel>
|
|
42
48
|
<DropdownMenuSeparator />
|
|
49
|
+
{userContext?.context.adminBusinessId && (
|
|
50
|
+
<DropdownMenuItem asChild>
|
|
51
|
+
<Link
|
|
52
|
+
to={{
|
|
53
|
+
pathname: ROUTES.BUSINESSES.DETAIL(userContext.context.adminBusinessId),
|
|
54
|
+
search: '?tab=admin',
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
<Shield className="size-4" />
|
|
58
|
+
<span className="hidden sm:inline">Admin Configurations</span>
|
|
59
|
+
</Link>
|
|
60
|
+
</DropdownMenuItem>
|
|
61
|
+
)}
|
|
43
62
|
<DropdownMenuItem>
|
|
44
63
|
<Button variant="ghost" onClick={() => setBalanceChargeModalOpen(true)}>
|
|
45
64
|
Add Balance Charge
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { type ReactElement } from 'react';
|
|
1
|
+
import { useCallback, type ReactElement } from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
|
-
import {
|
|
3
|
+
import type { ChargeFilter } from '../../gql/graphql.js';
|
|
4
|
+
import { useUrlQuery } from '../../hooks/use-url-query.js';
|
|
5
|
+
import { getBusinessTransactionsHref } from '../business-transactions/index.js';
|
|
4
6
|
|
|
5
7
|
type Props = {
|
|
6
8
|
account?: {
|
|
@@ -14,6 +16,33 @@ type Props = {
|
|
|
14
16
|
};
|
|
15
17
|
|
|
16
18
|
export const CounterpartyCell = ({ account, diffAccount }: Props): ReactElement => {
|
|
19
|
+
const { get } = useUrlQuery();
|
|
20
|
+
|
|
21
|
+
const encodedFilters = get('chargesFilters');
|
|
22
|
+
|
|
23
|
+
const getHref = useCallback(
|
|
24
|
+
(businessID: string) => {
|
|
25
|
+
let currentFilters: ChargeFilter = {};
|
|
26
|
+
if (encodedFilters) {
|
|
27
|
+
try {
|
|
28
|
+
const decoded = decodeURIComponent(encodedFilters);
|
|
29
|
+
const parsed = JSON.parse(decoded);
|
|
30
|
+
currentFilters = parsed as ChargeFilter;
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.error('Failed to parse filters from URL:', error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return getBusinessTransactionsHref({
|
|
37
|
+
ownerIds: currentFilters.byOwners || [],
|
|
38
|
+
businessIDs: [businessID],
|
|
39
|
+
...(currentFilters.fromDate && { fromDate: currentFilters.fromDate }),
|
|
40
|
+
...(currentFilters.toDate && { toDate: currentFilters.toDate }),
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
[encodedFilters],
|
|
44
|
+
);
|
|
45
|
+
|
|
17
46
|
const isAccountDiff = diffAccount && diffAccount?.id !== account?.id;
|
|
18
47
|
|
|
19
48
|
return (
|
|
@@ -22,7 +51,7 @@ export const CounterpartyCell = ({ account, diffAccount }: Props): ReactElement
|
|
|
22
51
|
<>
|
|
23
52
|
{account && (
|
|
24
53
|
<Link
|
|
25
|
-
to={
|
|
54
|
+
to={getHref(account.id)}
|
|
26
55
|
target="_blank"
|
|
27
56
|
rel="noreferrer"
|
|
28
57
|
onClick={event => event.stopPropagation()}
|
|
@@ -34,7 +63,7 @@ export const CounterpartyCell = ({ account, diffAccount }: Props): ReactElement
|
|
|
34
63
|
{isAccountDiff && diffAccount && (
|
|
35
64
|
<div className="border-2 border-yellow-500 rounded-md">
|
|
36
65
|
<Link
|
|
37
|
-
to={
|
|
66
|
+
to={getHref(diffAccount.id)}
|
|
38
67
|
target="_blank"
|
|
39
68
|
rel="noreferrer"
|
|
40
69
|
onClick={event => event.stopPropagation()}
|