From 769eaebc761c959c146de46576b4a66d149185d0 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Fri, 16 Jan 2026 18:52:12 +0200 Subject: [PATCH 1/5] fix(webapp): unexclude bank transactions --- .../commands/UnexcludeBankTransaction.service.ts | 12 +++++++----- .../DecrementUncategorizedTransactionOnExclude.ts | 4 ++-- packages/webapp/src/hooks/query/bank-rules.ts | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts b/packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts index 86e5f4525..3a3ec6d75 100644 --- a/packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts +++ b/packages/server/src/modules/BankingTransactionsExclude/commands/UnexcludeBankTransaction.service.ts @@ -4,8 +4,8 @@ import { validateTransactionShouldBeExcluded, } from './utils'; import { - IBankTransactionExcludedEventPayload, - IBankTransactionExcludingEventPayload, + IBankTransactionUnexcludedEventPayload, + IBankTransactionUnexcludingEventPayload, } from '../types/BankTransactionsExclude.types'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { Inject, Injectable } from '@nestjs/common'; @@ -24,7 +24,7 @@ export class UnexcludeBankTransactionService { private readonly uncategorizedBankTransactionModel: TenantModelProxy< typeof UncategorizedBankTransaction >, - ) {} + ) { } /** * Marks the given bank transaction as excluded. @@ -50,7 +50,8 @@ export class UnexcludeBankTransactionService { return this.uow.withTransaction(async (trx: Knex.Transaction) => { await this.eventEmitter.emitAsync(events.bankTransactions.onUnexcluding, { uncategorizedTransactionId, - } as IBankTransactionExcludingEventPayload); + trx, + } as IBankTransactionUnexcludingEventPayload); await this.uncategorizedBankTransactionModel() .query(trx) @@ -61,7 +62,8 @@ export class UnexcludeBankTransactionService { await this.eventEmitter.emitAsync(events.bankTransactions.onUnexcluded, { uncategorizedTransactionId, - } as IBankTransactionExcludedEventPayload); + trx, + } as IBankTransactionUnexcludedEventPayload); }); } } diff --git a/packages/server/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts b/packages/server/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts index ce56b324f..fc97d259a 100644 --- a/packages/server/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts +++ b/packages/server/src/modules/BankingTransactionsExclude/subscribers/DecrementUncategorizedTransactionOnExclude.ts @@ -19,7 +19,7 @@ export class DecrementUncategorizedTransactionOnExclude { private readonly uncategorizedBankTransaction: TenantModelProxy< typeof UncategorizedBankTransaction >, - ) {} + ) { } /** * Validates the cashflow transaction whether matched with bank transaction on deleting. @@ -50,7 +50,7 @@ export class DecrementUncategorizedTransactionOnExclude { trx, }: IBankTransactionUnexcludedEventPayload) { const transaction = await this.uncategorizedBankTransaction() - .query() + .query(trx) .findById(uncategorizedTransactionId); // await this.account() diff --git a/packages/webapp/src/hooks/query/bank-rules.ts b/packages/webapp/src/hooks/query/bank-rules.ts index e39edafce..998c6d9e7 100644 --- a/packages/webapp/src/hooks/query/bank-rules.ts +++ b/packages/webapp/src/hooks/query/bank-rules.ts @@ -424,7 +424,7 @@ export function useUnexcludeUncategorizedTransactions( UnexcludeBankTransactionsValue >( (value: { ids: Array }) => - apiRequest.delete(`/banking/exclude/bulk`, { ids: value.ids }), + apiRequest.delete(`/banking/exclude/bulk`, { data: { ids: value.ids } }), { onSuccess: (res, id) => { onValidateExcludeUncategorizedTransaction(queryClient); From 532aa07e7f58bb2e0010a755e29cc266cc37c17e Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Fri, 16 Jan 2026 19:08:07 +0200 Subject: [PATCH 2/5] fix(webapp): cancel the written-off invoice --- .../src/containers/Dialogs/BadDebtDialog/BadDebtForm.tsx | 7 +++---- .../containers/Dialogs/BadDebtDialog/BadDebtFormFields.tsx | 4 +++- .../webapp/src/containers/Dialogs/BadDebtDialog/index.tsx | 2 +- packages/webapp/src/hooks/query/invoices.tsx | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtForm.tsx b/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtForm.tsx index f9866c6d9..02e85f882 100644 --- a/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtForm.tsx +++ b/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtForm.tsx @@ -32,13 +32,12 @@ function BadDebtForm({ // #withCurrentOrganization organization: { base_currency }, }) { - const { invoice, dialogName, createBadDebtMutate, cancelBadDebtMutate } = - useBadDebtContext(); + const { invoice, dialogName, createBadDebtMutate } = useBadDebtContext(); // Initial form values const initialValues = { ...defaultInitialValues, - amount: invoice.due_amount, + amount: invoice?.due_amount || '', }; // Handles the form submit. @@ -67,7 +66,7 @@ function BadDebtForm({ } setSubmitting(false); }; - createBadDebtMutate([invoice.id, form]).then(onSuccess).catch(onError); + createBadDebtMutate([invoice?.id, form]).then(onSuccess).catch(onError); }; return ( diff --git a/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.tsx b/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.tsx index afd59aa4b..8f228e05b 100644 --- a/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.tsx +++ b/packages/webapp/src/containers/Dialogs/BadDebtDialog/BadDebtFormFields.tsx @@ -5,6 +5,7 @@ import { FMoneyInputGroup, FTextArea, FormattedMessage as T, + FFormGroup, } from '@/components'; import { useAutofocus } from '@/hooks'; @@ -53,7 +54,7 @@ function BadDebtFormFields() { fill > - + diff --git a/packages/webapp/src/containers/Dialogs/BadDebtDialog/index.tsx b/packages/webapp/src/containers/Dialogs/BadDebtDialog/index.tsx index 690e7b2e5..5582626cb 100644 --- a/packages/webapp/src/containers/Dialogs/BadDebtDialog/index.tsx +++ b/packages/webapp/src/containers/Dialogs/BadDebtDialog/index.tsx @@ -16,7 +16,7 @@ function BadDebtDialog({ dialogName, payload: { invoiceId = null }, isOpen }) { name={dialogName} title={} isOpen={isOpen} - canEscapeJeyClose={true} + canEscapeKeyClose={true} autoFocus={true} className={'dialog--bad-debt'} > diff --git a/packages/webapp/src/hooks/query/invoices.tsx b/packages/webapp/src/hooks/query/invoices.tsx index a3e45755d..00221f845 100644 --- a/packages/webapp/src/hooks/query/invoices.tsx +++ b/packages/webapp/src/hooks/query/invoices.tsx @@ -341,7 +341,7 @@ export function useCancelBadDebt(props) { const apiRequest = useApiRequest(); return useMutation( - (id) => apiRequest.post(`sale-invoices/${id}/writeoff/cancel`), + (id) => apiRequest.post(`sale-invoices/${id}/cancel-writeoff`), { onSuccess: (res, id) => { // Invalidate From 7ee161733fc4f54a712acca628636d502a9ee0b1 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sat, 17 Jan 2026 21:42:27 +0200 Subject: [PATCH 3/5] fix: landed cost dialog --- packages/server/src/i18n/en/bill.json | 5 ++- .../BillLandedCosts/LandedCost.controller.ts | 2 +- ...AllocatedLandedCostTransactions.service.ts | 11 ++++- .../LandedCostTransactions.service.ts | 6 +-- .../dtos/AllocateBillLandedCost.dto.ts | 6 +-- .../BillLandedCosts/models/BillLandedCost.ts | 4 +- .../AllocateLandedCostDialogProvider.tsx | 6 ++- .../AllocateLandedCostFloatingActions.tsx | 11 +++-- .../AllocateLandedCostFormFields.tsx | 42 +++++++++++++------ .../webapp/src/hooks/query/landedCost.tsx | 3 -- .../AllocateLandedCostForm.scss | 14 ++++++- 11 files changed, 77 insertions(+), 33 deletions(-) diff --git a/packages/server/src/i18n/en/bill.json b/packages/server/src/i18n/en/bill.json index ab3740a07..92ee0a933 100644 --- a/packages/server/src/i18n/en/bill.json +++ b/packages/server/src/i18n/en/bill.json @@ -22,6 +22,9 @@ "field.status.unpaid": "Unpaid", "field.status.opened": "Opened", "field.status.draft": "Draft", - "field.created_at": "Created At" + "field.created_at": "Created At", + "allocation_method": "Allocation Method", + "allocation_method.quantity": "Quantity", + "allocation_method.value": "Valuation" } diff --git a/packages/server/src/modules/BillLandedCosts/LandedCost.controller.ts b/packages/server/src/modules/BillLandedCosts/LandedCost.controller.ts index 6ed7ed8a5..bed8535b0 100644 --- a/packages/server/src/modules/BillLandedCosts/LandedCost.controller.ts +++ b/packages/server/src/modules/BillLandedCosts/LandedCost.controller.ts @@ -25,7 +25,7 @@ export class BillAllocateLandedCostController { private billAllocatedCostTransactions: BillAllocatedLandedCostTransactions, private revertAllocatedLandedCost: RevertAllocatedLandedCost, private landedCostTransactions: LandedCostTranasctions, - ) {} + ) { } @Get('/transactions') @ApiOperation({ summary: 'Get landed cost transactions' }) diff --git a/packages/server/src/modules/BillLandedCosts/commands/BillAllocatedLandedCostTransactions.service.ts b/packages/server/src/modules/BillLandedCosts/commands/BillAllocatedLandedCostTransactions.service.ts index 49764b6a8..a50af6284 100644 --- a/packages/server/src/modules/BillLandedCosts/commands/BillAllocatedLandedCostTransactions.service.ts +++ b/packages/server/src/modules/BillLandedCosts/commands/BillAllocatedLandedCostTransactions.service.ts @@ -21,7 +21,7 @@ export class BillAllocatedLandedCostTransactions { private readonly billLandedCostModel: TenantModelProxy< typeof BillLandedCost >, - ) {} + ) { } /** * Retrieve the bill associated landed cost transactions. @@ -77,6 +77,13 @@ export class BillAllocatedLandedCostTransactions { transaction.fromTransactionType, transaction, ); + const allocationMethodFormattedKey = transaction.allocationMethodFormatted; + const allocationMethodFormatted = allocationMethodFormattedKey + ? this.i18nService.t(allocationMethodFormattedKey, { + defaultValue: allocationMethodFormattedKey, + }) + : ''; + return { formattedAmount: formatNumber(transaction.amount, { currencyCode: transaction.currencyCode, @@ -84,12 +91,14 @@ export class BillAllocatedLandedCostTransactions { ...omit(transaction, [ 'allocatedFromBillEntry', 'allocatedFromExpenseEntry', + 'allocationMethodFormatted', ]), name, description, formattedLocalAmount: formatNumber(transaction.localAmount, { currencyCode: 'USD', }), + allocationMethodFormatted, }; }; diff --git a/packages/server/src/modules/BillLandedCosts/commands/LandedCostTransactions.service.ts b/packages/server/src/modules/BillLandedCosts/commands/LandedCostTransactions.service.ts index c15c83da5..6b866779c 100644 --- a/packages/server/src/modules/BillLandedCosts/commands/LandedCostTransactions.service.ts +++ b/packages/server/src/modules/BillLandedCosts/commands/LandedCostTransactions.service.ts @@ -14,7 +14,7 @@ import { LandedCostTransactionsQueryDto } from '../dtos/LandedCostTransactionsQu @Injectable() export class LandedCostTranasctions { - constructor(private readonly transactionLandedCost: TransactionLandedCost) {} + constructor(private readonly transactionLandedCost: TransactionLandedCost) { } /** * Retrieve the landed costs based on the given query. @@ -45,8 +45,8 @@ export class LandedCostTranasctions { )(transactionType); return pipe( - this.transformLandedCostTransactions, R.map(transformLandedCost), + this.transformLandedCostTransactions, )(transactions); }; @@ -90,7 +90,7 @@ export class LandedCostTranasctions { const entries = R.map< ILandedCostTransactionEntry, ILandedCostTransactionEntryDOJO - >(transformLandedCostEntry)(transaction.entries); + >(transformLandedCostEntry)(transaction.entries ?? []); return { ...transaction, diff --git a/packages/server/src/modules/BillLandedCosts/dtos/AllocateBillLandedCost.dto.ts b/packages/server/src/modules/BillLandedCosts/dtos/AllocateBillLandedCost.dto.ts index 063157e96..2cc4f833d 100644 --- a/packages/server/src/modules/BillLandedCosts/dtos/AllocateBillLandedCost.dto.ts +++ b/packages/server/src/modules/BillLandedCosts/dtos/AllocateBillLandedCost.dto.ts @@ -4,7 +4,6 @@ import { IsOptional, IsArray, ValidateNested, - IsDecimal, IsString, IsNumber, } from 'class-validator'; @@ -17,8 +16,9 @@ export class AllocateBillLandedCostItemDto { @ToNumber() entryId: number; - @IsDecimal() - cost: string; // Use string for IsDecimal, or use @IsNumber() if you want a number + @IsNumber() + @ToNumber() + cost: number; } export class AllocateBillLandedCostDto { diff --git a/packages/server/src/modules/BillLandedCosts/models/BillLandedCost.ts b/packages/server/src/modules/BillLandedCosts/models/BillLandedCost.ts index 4cf568cef..80347fe7e 100644 --- a/packages/server/src/modules/BillLandedCosts/models/BillLandedCost.ts +++ b/packages/server/src/modules/BillLandedCosts/models/BillLandedCost.ts @@ -60,8 +60,8 @@ export class BillLandedCost extends BaseModel { const allocationMethod = lowerCase(this.allocationMethod); const keyLabelsPairs = { - value: 'allocation_method.value.label', - quantity: 'allocation_method.quantity.label', + value: 'bill.allocation_method.value', + quantity: 'bill.allocation_method.quantity', }; return keyLabelsPairs[allocationMethod] || ''; } diff --git a/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.tsx b/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.tsx index 7bdb46617..69d59289b 100644 --- a/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.tsx +++ b/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostDialogProvider.tsx @@ -24,7 +24,7 @@ function AllocateLandedCostDialogProvider({ dialogName, ...props }) { - const [transactionsType, setTransactionsType] = React.useState(null); + const [transactionsType, setTransactionsType] = React.useState('Bill'); const [transactionId, setTransactionId] = React.useState(null); const [transactionEntryId, setTransactionEntryId] = React.useState(null); @@ -34,7 +34,8 @@ function AllocateLandedCostDialogProvider({ }); // Retrieve the landed cost transactions based on the given transactions type. const { - data: { transactions: landedCostTransactions }, + data: landedCostTransactions, + isLoading: isLandedCostTransactionsLoading, } = useLandedCostTransaction(transactionsType, { enabled: !!transactionsType, }); @@ -88,6 +89,7 @@ function AllocateLandedCostDialogProvider({ costTransactionEntries, transactionsType, landedCostTransactions, + isLandedCostTransactionsLoading, setTransactionsType, setTransactionId, setTransactionEntryId, diff --git a/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.tsx b/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.tsx index 3959da626..5ec9bd0d6 100644 --- a/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.tsx +++ b/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFloatingActions.tsx @@ -38,7 +38,7 @@ function AllocateLandedCostFloatingActions({ {costTransactionEntry && ( - + {formattedUnallocatedCostAmount} )} @@ -68,11 +68,16 @@ const AllocateDialogFooter = styled(DialogFooter)` `; const UnallocatedAmount = styled.div` - color: #3f5278; + --x-color-text: #3f5278; + + .bp4-dark & { + --x-color-text: var(--color-light-gray1); + } + color: var(--x-color-text); align-self: center; strong { - color: #353535; + color: var(--x-color-text); padding-left: 4px; } `; diff --git a/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.tsx b/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.tsx index 6b8af1446..6f482a42a 100644 --- a/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.tsx +++ b/packages/webapp/src/containers/Dialogs/AllocateLandedCostDialog/AllocateLandedCostFormFields.tsx @@ -8,8 +8,10 @@ import { RadioGroup, Radio, InputGroup, + Spinner, } from '@blueprintjs/core'; import classNames from 'classnames'; +import { x } from '@xstyled/emotion'; import { FormattedMessage as T, If, FFormGroup, FSelect, FRadioGroup, FInputGroup } from '@/components'; import { handleStringChange } from '@/utils'; import { FieldRequiredHint } from '@/components'; @@ -28,7 +30,7 @@ import { useAllocateLandedConstDialogContext } from './AllocateLandedCostDialogP */ export default function AllocateLandedCostFormFields() { // Allocated landed cost dialog. - const { costTransactionEntries, landedCostTransactions } = + const { costTransactionEntries, landedCostTransactions, isLandedCostTransactionsLoading } = useAllocateLandedConstDialogContext(); const { values, setFieldValue, form } = useFormikContext(); @@ -97,21 +99,35 @@ export default function AllocateLandedCostFormFields() { inline fill > - + + + {isLandedCostTransactionsLoading && ( + + + + )} + {/*------------ Transaction line -----------*/} - 0}> + 0}> } diff --git a/packages/webapp/src/hooks/query/landedCost.tsx b/packages/webapp/src/hooks/query/landedCost.tsx index 1d6279c05..b3e217e08 100644 --- a/packages/webapp/src/hooks/query/landedCost.tsx +++ b/packages/webapp/src/hooks/query/landedCost.tsx @@ -67,9 +67,6 @@ export function useLandedCostTransaction(query, props) { }, { select: (res) => res.data, - defaultData: { - transactions: [], - }, ...props, }, ); diff --git a/packages/webapp/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss b/packages/webapp/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss index 71a87b4aa..18c3c557c 100644 --- a/packages/webapp/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss +++ b/packages/webapp/src/style/pages/AllocateLandedCost/AllocateLandedCostForm.scss @@ -21,7 +21,7 @@ } .bp4-dialog-footer{ - padding-top: 10px; + // padding-top: 10px; } .bigcapital-datatable { @@ -30,6 +30,10 @@ border: 1px solid #d1dee2; min-width: auto; + .bp4-dark & { + border-color: var(--color-dark-gray5); + } + .tbody, .tbody-inner { height: auto; @@ -43,6 +47,10 @@ padding: 0.4rem; margin-left: -1px; border-left: 1px solid #ececec; + + .bp4-dark & { + border-left-color: var(--color-dark-gray5); + } } .bp4-form-group{ @@ -51,6 +59,10 @@ &:not(.bp4-intent-danger) .bp4-input{ border: 1px solid #d0dfe2; + .bp4-dark & { + border-color: var(--color-dark-gray5); + } + &:focus{ box-shadow: 0 0 0 1px #116cd0; border-color: #116cd0; From 3dfe8844133a3e077e4c93281481f7cf830bc17b Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sat, 17 Jan 2026 23:33:10 +0200 Subject: [PATCH 4/5] fix(webapp): pagination darkmode --- .../src/components/Datatable/Pagination.tsx | 164 ++++++++++++++---- .../ExcludedTransactions/_utils.tsx | 5 +- 2 files changed, 132 insertions(+), 37 deletions(-) diff --git a/packages/webapp/src/components/Datatable/Pagination.tsx b/packages/webapp/src/components/Datatable/Pagination.tsx index 2dd1186ba..2bd10a643 100644 --- a/packages/webapp/src/components/Datatable/Pagination.tsx +++ b/packages/webapp/src/components/Datatable/Pagination.tsx @@ -1,14 +1,115 @@ // @ts-nocheck import React, { useReducer, useEffect } from 'react'; -import classNames from 'classnames'; import { Button, ButtonGroup, Intent, HTMLSelect } from '@blueprintjs/core'; -import { FormattedMessage as T } from '@/components'; import intl from 'react-intl-universal'; import PropTypes from 'prop-types'; import { range } from 'lodash'; -import { Icon } from '@/components'; +import styled from 'styled-components'; +import { x } from '@xstyled/emotion'; +import { Icon, FormattedMessage as T } from '@/components'; +import { useIsDarkMode } from '@/hooks/useDarkMode'; -import '@/style/components/DataTable/Pagination.scss'; +// Styled components +const StyledButtonGroup = styled(ButtonGroup)` + .bp4-button { + background: transparent; + padding: 5px; + } +`; + +const StyledPaginationButton = styled(Button)` + --x-button-text-color: #666666; + --x-button-hover-background: #E6EFFB; + --x-button-active-text-color: #000; + --x-button-active-background: #E6EFFB; + --x-button-active-disabled-background: #E6EFFB; + + .bp4-dark & { + --x-button-text-color: rgba(255, 255, 255, 0.8); + --x-button-hover-background: var(--color-dark-gray3); + --x-button-active-text-color: var(--color-light-gray2); + --x-button-active-background: var(--color-dark-gray3); + --x-button-active-disabled-background: var(--color-dark-gray3); + } + min-width: 24px; + min-height: 24px; + border-radius: 5px; + + &:not([class*="bp4-intent-"]).bp4-minimal { + color: var(--x-button-text-color); + + &:hover { + background-color: var(--x-button-hover-background); + } + .bp4-icon { + margin-right: 4px; + color: var(--x-button-text-color); + } + } + &.is-active { + &.bp4-intent-primary.bp4-minimal:disabled, + &.bp4-intent-primary.bp4-minimal.bp4-disabled { + background-color: var(--x-button-active-disabled-background); + + .bp4-button-text { + color: var(--x-button-active-text-color); + } + } + } +`; + +const StyledPreviousButton = styled(StyledPaginationButton)` + padding-left: 10px; + padding-right: 10px; + + .bp4-icon { + [dir="rtl"] & { + transform: scale(-1); + } + } +`; + +const StyledNextButton = styled(StyledPaginationButton)` + padding-left: 10px; + padding-right: 10px; + + .bp4-icon { + order: 1; + margin-right: 0; + margin-left: 4px; + } +`; + +const StyledHTMLSelect = styled(HTMLSelect)` + --x-html-select-text-color: #666; + --x-html-select-border-color: #e8e8e8; + + .bp4-dark & { + --x-html-select-text-color: rgba(255, 255, 255, 0.8); + --x-html-select-border-color: rgba(255, 255, 255, 0.15); + } + &.bp4-html-select.bp4-minimal { + margin-left: 6px; + + select { + height: 24px; + width: auto; + padding: 0; + padding-right: 14px; + padding-left: 8px; + border: 1px solid var(--x-html-select-border-color); + font-size: 13px; + border-radius: 3px; + color: var(--x-html-select-text-color); + } + &::after { + border-left-width: 3px; + border-right-width: 3px; + border-top-width: 4px; + margin-right: 6px; + } + } +`; const TYPE = { PAGE_CHANGE: 'PAGE_CHANGE', @@ -91,6 +192,7 @@ export function Pagination({ onPageChange, onPageSizeChange, }) { + const isDark = useIsDarkMode(); const [state, dispatch] = useReducer( reducer, { currentPage, total, size }, @@ -107,10 +209,10 @@ export function Pagination({ }, [total, size, currentPage]); return ( - + + ); } diff --git a/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx b/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx index 9ecd78f86..0f62e8afe 100644 --- a/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx +++ b/packages/webapp/src/containers/CashFlow/AccountTransactions/ExcludedTransactions/_utils.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { getColumnWidth } from '@/utils'; import { useExcludedTransactionsBoot } from './ExcludedTransactionsTableBoot'; +import { CLASSES } from '@/constants'; const getReportColWidth = (data, accessor, headerText) => { return getColumnWidth( @@ -13,7 +14,7 @@ const getReportColWidth = (data, accessor, headerText) => { }; const descriptionAccessor = (transaction) => { - return {transaction.description}; + return {transaction.description}; }; /** @@ -37,7 +38,7 @@ export function useExcludedTransactionsColumns() { () => [ { Header: 'Date', - accessor: 'formatted_date', + accessor: 'formatted_date', width: 110, }, { From 458093fca212ac2ca16a7b9dd6d8e540b854b464 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 18 Jan 2026 14:59:20 +0200 Subject: [PATCH 5/5] fix(server): move global filters, pipes, and interceptors to AppModule --- packages/server/src/main.ts | 12 ---------- packages/server/src/modules/App/App.module.ts | 22 ++++++++++++++++++- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/server/src/main.ts b/packages/server/src/main.ts index 1cd28fd0f..e4ebaebd3 100644 --- a/packages/server/src/main.ts +++ b/packages/server/src/main.ts @@ -4,10 +4,6 @@ import { ClsMiddleware } from 'nestjs-cls'; import * as path from 'path'; import './utils/moment-mysql'; import { AppModule } from './modules/App/App.module'; -import { ServiceErrorFilter } from './common/filters/service-error.filter'; -import { ModelHasRelationsFilter } from './common/filters/model-has-relations.filter'; -import { ValidationPipe } from './common/pipes/ClassValidation.pipe'; -import { ToJsonInterceptor } from './common/interceptors/to-json.interceptor'; import { NestExpressApplication } from '@nestjs/platform-express'; global.__public_dirname = path.join(__dirname, '..', 'public'); @@ -25,11 +21,6 @@ async function bootstrap() { // create and mount the middleware manually here app.use(new ClsMiddleware({}).use); - app.useGlobalInterceptors(new ToJsonInterceptor()); - - // use the validation pipe globally - app.useGlobalPipes(new ValidationPipe()); - const config = new DocumentBuilder() .setTitle('Bigcapital') .setDescription('Financial accounting software') @@ -39,9 +30,6 @@ async function bootstrap() { const documentFactory = () => SwaggerModule.createDocument(app, config); SwaggerModule.setup('swagger', app, documentFactory); - app.useGlobalFilters(new ServiceErrorFilter()); - app.useGlobalFilters(new ModelHasRelationsFilter()); - await app.listen(process.env.PORT ?? 3000); } bootstrap(); diff --git a/packages/server/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts index 98d69d3f0..ded1ffda5 100644 --- a/packages/server/src/modules/App/App.module.ts +++ b/packages/server/src/modules/App/App.module.ts @@ -1,7 +1,7 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { EventEmitterModule } from '@nestjs/event-emitter'; -import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core'; +import { APP_GUARD, APP_INTERCEPTOR, APP_PIPE, APP_FILTER } from '@nestjs/core'; import { join } from 'path'; import { ServeStaticModule } from '@nestjs/serve-static'; import { RedisModule } from '@liaoliaots/nestjs-redis'; @@ -36,6 +36,10 @@ import { PdfTemplatesModule } from '../PdfTemplate/PdfTemplates.module'; import { BranchesModule } from '../Branches/Branches.module'; import { WarehousesModule } from '../Warehouses/Warehouses.module'; import { SerializeInterceptor } from '@/common/interceptors/serialize.interceptor'; +import { ValidationPipe } from '@/common/pipes/ClassValidation.pipe'; +import { ToJsonInterceptor } from '@/common/interceptors/to-json.interceptor'; +import { ServiceErrorFilter } from '@/common/filters/service-error.filter'; +import { ModelHasRelationsFilter } from '@/common/filters/model-has-relations.filter'; import { ChromiumlyTenancyModule } from '../ChromiumlyTenancy/ChromiumlyTenancy.module'; import { CustomersModule } from '../Customers/Customers.module'; import { VendorsModule } from '../Vendors/Vendors.module'; @@ -234,10 +238,18 @@ import { AppThrottleModule } from './AppThrottle.module'; ], controllers: [AppController], providers: [ + { + provide: APP_PIPE, + useClass: ValidationPipe, + }, { provide: APP_GUARD, useClass: ThrottlerGuard, }, + { + provide: APP_INTERCEPTOR, + useClass: ToJsonInterceptor, + }, { provide: APP_INTERCEPTOR, useClass: SerializeInterceptor, @@ -250,6 +262,14 @@ import { AppThrottleModule } from './AppThrottle.module'; provide: APP_INTERCEPTOR, useClass: ExcludeNullInterceptor, }, + { + provide: APP_FILTER, + useClass: ServiceErrorFilter, + }, + { + provide: APP_FILTER, + useClass: ModelHasRelationsFilter, + }, AppService, ], })